pax_global_header00006660000000000000000000000064127477036650014533gustar00rootroot0000000000000052 comment=eff67b56e33b9c1a7488ba932ec3e438556015cc luv-1.9.1-0/000077500000000000000000000000001274770366500125065ustar00rootroot00000000000000luv-1.9.1-0/.ci/000077500000000000000000000000001274770366500131575ustar00rootroot00000000000000luv-1.9.1-0/.ci/install.bat000066400000000000000000000200631274770366500153160ustar00rootroot00000000000000@echo off cd %APPVEYOR_BUILD_FOLDER% :: ========================================================= :: Set some defaults. Infer some variables. :: :: These are set globally if "%LUA_VER%" NEQ "" ( set LUA=lua set LUA_SHORTV=%LUA_VER:~0,3% ) else ( set LUA=luajit set LJ_SHORTV=%LJ_VER:~0,3% set LUA_SHORTV=5.1 ) :: defines LUA_DIR so Cmake can find this Lua install if "%LUA%"=="luajit" ( set LUA_DIR=c:\lua\%platform%\lj%LJ_SHORTV% ) else ( set LUA_DIR=c:\lua\%platform%\%LUA_VER% ) :: Now we declare a scope Setlocal EnableDelayedExpansion EnableExtensions if not defined LUAROCKS_URL set LUAROCKS_URL=http://keplerproject.github.io/luarocks/releases if not defined LUAROCKS_REPO set LUAROCKS_REPO=https://luarocks.org if not defined LUA_URL set LUA_URL=http://www.lua.org/ftp if defined NOCOMPAT ( set COMPATFLAG=--nocompat ) else ( set COMPATFLAG= ) if not defined LUAJIT_GIT_REPO set LUAJIT_GIT_REPO=https://github.com/LuaJIT/LuaJIT.git if not defined LUAJIT_URL set LUAJIT_URL=https://github.com/LuaJIT/LuaJIT/archive if not defined LR_EXTERNAL set LR_EXTERNAL=c:\external if not defined LUAROCKS_INSTALL set LUAROCKS_INSTALL=%LUA_DIR%\LuaRocks :: LuaRocks <= 2.2.2 used a versioned directory :: HEAD and newer versions do not, so act accordingly. if defined LR_ROOT goto :skiplrver if "%LUAROCKS_VER%" EQU "HEAD" ( set LR_ROOT=%LUAROCKS_INSTALL% goto :skiplrver ) set LR_ROOT=%LUAROCKS_INSTALL% if %LUAROCKS_VER:~0,1% LEQ 2 ( if %LUAROCKS_VER:~2,1% LEQ 2 ( if %LUAROCKS_VER:~4,1% LEQ 3 ( set LR_ROOT=%LUAROCKS_INSTALL%\!LUAROCKS_VER:~0,3! ) ) ) :skiplrver if not defined LR_SYSTREE set LR_SYSTREE=%LUAROCKS_INSTALL%\systree if not defined SEVENZIP set SEVENZIP=7z :: :: ========================================================= :: first create some necessary directories: mkdir downloads 2>NUL :: Download and compile Lua (or LuaJIT) if "%LUA%"=="luajit" ( if not exist %LUA_DIR% ( if "%LJ_SHORTV%"=="2.1" ( :: Clone repository and checkout 2.1 branch set lj_source_folder=%APPVEYOR_BUILD_FOLDER%\downloads\luajit-%LJ_VER% if not exist !lj_source_folder! ( echo Cloning git repo %LUAJIT_GIT_REPO% !lj_source_folder! git clone %LUAJIT_GIT_REPO% !lj_source_folder! || call :die "Failed to clone repository" ) else ( cd !lj_source_folder! git pull || call :die "Failed to update repository" ) cd !lj_source_folder!\src git checkout v2.1 || call :die ) else ( set lj_source_folder=%APPVEYOR_BUILD_FOLDER%\downloads\luajit-%LJ_VER% if not exist !lj_source_folder! ( echo Downloading... %LUAJIT_URL%/v%LJ_VER%.tar.gz curl --location --silent --fail --max-time 120 --connect-timeout 30 %LUAJIT_URL%/v%LJ_VER%.tar.gz | %SEVENZIP% x -si -so -tgzip | %SEVENZIP% x -si -ttar -aoa -odownloads ) cd !lj_source_folder!\src ) :: Compiles LuaJIT if "%Configuration%"=="MinGW" ( call mingw32-make ) else ( call msvcbuild.bat ) mkdir %LUA_DIR% 2> NUL for %%a in (bin bin\lua bin\lua\jit include lib) do ( mkdir "%LUA_DIR%\%%a" ) for %%a in (luajit.exe lua51.dll) do ( move "!lj_source_folder!\src\%%a" "%LUA_DIR%\bin" ) copy "%LUA_DIR%\bin\luajit.exe" "%LUA_DIR%\bin\lua.exe" move "!lj_source_folder!\src\lua51.lib" "%LUA_DIR%\lib" for %%a in (lauxlib.h lua.h lua.hpp luaconf.h lualib.h luajit.h) do ( copy "!lj_source_folder!\src\%%a" "%LUA_DIR%\include" ) copy "!lj_source_folder!\src\jit\*.lua" "%LUA_DIR%\bin\lua\jit" ) else ( echo LuaJIT %LJ_VER% already installed at %LUA_DIR% ) ) else ( if not exist %LUA_DIR% ( :: Download and compile Lua if not exist downloads\lua-%LUA_VER% ( curl --silent --fail --max-time 120 --connect-timeout 30 %LUA_URL%/lua-%LUA_VER%.tar.gz | %SEVENZIP% x -si -so -tgzip | %SEVENZIP% x -si -ttar -aoa -odownloads ) mkdir downloads\lua-%LUA_VER%\etc 2> NUL copy %~dp0\winmake.bat downloads\lua-%LUA_VER%\etc\winmake.bat cd downloads\lua-%LUA_VER% call etc\winmake %COMPATFLAG% call etc\winmake install %LUA_DIR% ) else ( echo Lua %LUA_VER% already installed at %LUA_DIR% ) ) if not exist %LUA_DIR%\bin\%LUA%.exe call :die "Missing Lua interpreter at %LUA_DIR%\bin\%LUA%.exe" set PATH=%LUA_DIR%\bin;%PATH% call !LUA! -v :: ========================================================== :: LuaRocks :: ========================================================== if not exist "%LR_ROOT%" ( :: Downloads and installs LuaRocks cd %APPVEYOR_BUILD_FOLDER% if %LUAROCKS_VER%==HEAD ( set lr_source_folder=%APPVEYOR_BUILD_FOLDER%\downloads\luarocks-%LUAROCKS_VER%-win32 if not exist !lr_source_folder! ( git clone https://github.com/keplerproject/luarocks.git --single-branch --depth 1 !lr_source_folder! || call :die "Failed to clone LuaRocks repository" ) else ( cd !lr_source_folder! git pull || call :die "Failed to update LuaRocks repository" ) ) else ( if not exist downloads\luarocks-%LUAROCKS_VER%-win32.zip ( echo Downloading LuaRocks... curl --silent --fail --max-time 120 --connect-timeout 30 --output downloads\luarocks-%LUAROCKS_VER%-win32.zip %LUAROCKS_URL%/luarocks-%LUAROCKS_VER%-win32.zip %SEVENZIP% x -aoa -odownloads downloads\luarocks-%LUAROCKS_VER%-win32.zip ) ) cd downloads\luarocks-%LUAROCKS_VER%-win32 if "%Configuration%"=="MinGW" ( call install.bat /LUA %LUA_DIR% /Q /LV %LUA_SHORTV% /P "%LUAROCKS_INSTALL%" /TREE "%LR_SYSTREE%" /MW ) else ( call install.bat /LUA %LUA_DIR% /Q /LV %LUA_SHORTV% /P "%LUAROCKS_INSTALL%" /TREE "%LR_SYSTREE%" ) :: Configures LuaRocks to instruct CMake the correct generator to use. Else, CMake will pick the highest :: Visual Studio version installed if "%Configuration%"=="MinGW" ( echo cmake_generator = "MinGW Makefiles" >> %LUAROCKS_INSTALL%\config-%LUA_SHORTV%.lua ) else ( set MSVS_GENERATORS[2008]=Visual Studio 9 2008 set MSVS_GENERATORS[2010]=Visual Studio 10 2010 set MSVS_GENERATORS[2012]=Visual Studio 11 2012 set MSVS_GENERATORS[2013]=Visual Studio 12 2013 set MSVS_GENERATORS[2015]=Visual Studio 14 2015 set CMAKE_GENERATOR=!MSVS_GENERATORS[%Configuration%]! if "%platform%" EQU "x64" (set CMAKE_GENERATOR=!CMAKE_GENERATOR! Win64) echo cmake_generator = "!CMAKE_GENERATOR!" >> %LUAROCKS_INSTALL%\config-%LUA_SHORTV%.lua ) ) if not exist "%LR_ROOT%" call :die "LuaRocks not found at %LR_ROOT%" set PATH=%LR_ROOT%;%LR_SYSTREE%\bin;%PATH% :: Lua will use just the system rocks set LUA_PATH=%LR_ROOT%\lua\?.lua;%LR_ROOT%\lua\?\init.lua set LUA_PATH=%LUA_PATH%;%LR_SYSTREE%\share\lua\%LUA_SHORTV%\?.lua set LUA_PATH=%LUA_PATH%;%LR_SYSTREE%\share\lua\%LUA_SHORTV%\?\init.lua set LUA_PATH=%LUA_PATH%;.\?.lua;.\?\init.lua set LUA_CPATH=%LR_SYSTREE%\lib\lua\%LUA_SHORTV%\?.dll;.\?.dll call luarocks --version || call :die "Error with LuaRocks installation" call luarocks list if not exist "%LR_EXTERNAL%" ( mkdir "%LR_EXTERNAL%" mkdir "%LR_EXTERNAL%\lib" mkdir "%LR_EXTERNAL%\include" ) set PATH=%LR_EXTERNAL%;%PATH% :: Exports the following variables: :: (beware of whitespace between & and ^ below) endlocal & set PATH=%PATH%&^ set LR_SYSTREE=%LR_SYSTREE%&^ set LUA_PATH=%LUA_PATH%&^ set LUA_CPATH=%LUA_CPATH%&^ set LR_EXTERNAL=%LR_EXTERNAL% echo. echo ====================================================== if "%LUA%"=="luajit" ( echo Installation of LuaJIT %LJ_VER% and LuaRocks %LUAROCKS_VER% done. ) else ( echo Installation of Lua %LUA_VER% and LuaRocks %LUAROCKS_VER% done. if defined NOCOMPAT echo Lua was built with compatibility flags disabled. ) echo Platform - %platform% echo LUA - %LUA% echo LUA_SHORTV - %LUA_SHORTV% echo LJ_SHORTV - %LJ_SHORTV% echo LUA_PATH - %LUA_PATH% echo LUA_CPATH - %LUA_CPATH% echo. echo LR_EXTERNAL - %LR_EXTERNAL% echo ====================================================== echo. goto :eof :: This blank space is intentional. If you see errors like "The system cannot find the batch label specified 'foo'" :: then try adding or removing blank lines lines above. :: Yes, really. :: http://stackoverflow.com/questions/232651/why-the-system-cannot-find-the-batch-label-specified-is-thrown-even-if-label-e :: helper functions: :: for bailing out when an error occurred :die %1 echo %1 exit /B 1 goto :eof luv-1.9.1-0/.ci/platform.sh000066400000000000000000000003711274770366500153400ustar00rootroot00000000000000if [ -z "${PLATFORM:-}" ]; then PLATFORM=$TRAVIS_OS_NAME; fi if [ "$PLATFORM" == "osx" ]; then PLATFORM="macosx"; fi if [ -z "$PLATFORM" ]; then if [ "$(uname)" == "Linux" ]; then PLATFORM="linux"; else PLATFORM="macosx"; fi; fi luv-1.9.1-0/.ci/set_compiler_env.bat000066400000000000000000000017411274770366500172070ustar00rootroot00000000000000@echo off :: Now we declare a scope Setlocal EnableDelayedExpansion EnableExtensions if not defined Configuration set Configuration=2015 if "%Configuration%"=="MinGW" ( goto :mingw ) set arch=x86 if "%platform%" EQU "x64" ( set arch=x86_amd64 ) if "%Configuration%"=="2015" ( set SET_VS_ENV="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" ) if "%Configuration%"=="2013" ( set SET_VS_ENV="C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" ) if "%Configuration%"=="2012" ( set SET_VS_ENV="C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat" ) if "%Configuration%"=="2010" ( set SET_VS_ENV="C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" ) if "%Configuration%"=="2008" ( set SET_VS_ENV="C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat" ) :: Visual Studio detected endlocal & call %SET_VS_ENV% %arch% goto :eof :: MinGW detected :mingw endlocal & set PATH=c:\mingw\bin;%PATH% luv-1.9.1-0/.ci/setenv_lua.sh000066400000000000000000000002171274770366500156600ustar00rootroot00000000000000export PATH=${PATH}:$HOME/.lua:$HOME/.local/bin:${TRAVIS_BUILD_DIR}/install/luarocks/bin bash .ci/setup_lua.sh eval `$HOME/.lua/luarocks path` luv-1.9.1-0/.ci/setup_lua.sh000066400000000000000000000056511274770366500155230ustar00rootroot00000000000000#! /bin/bash # A script for setting up environment for travis-ci testing. # Sets up Lua and Luarocks. # LUA must be "lua5.1", "lua5.2" or "luajit". # luajit2.0 - master v2.0 # luajit2.1 - master v2.1 set -eufo pipefail LUAJIT_VERSION="2.0.4" LUAJIT_BASE="LuaJIT-$LUAJIT_VERSION" source .ci/platform.sh LUA_HOME_DIR=$TRAVIS_BUILD_DIR/install/lua LR_HOME_DIR=$TRAVIS_BUILD_DIR/install/luarocks mkdir $HOME/.lua LUAJIT="no" if [ "$PLATFORM" == "macosx" ]; then if [ "$LUA" == "luajit" ]; then LUAJIT="yes"; fi if [ "$LUA" == "luajit2.0" ]; then LUAJIT="yes"; fi if [ "$LUA" == "luajit2.1" ]; then LUAJIT="yes"; fi; elif [ "$(expr substr $LUA 1 6)" == "luajit" ]; then LUAJIT="yes"; fi mkdir -p "$LUA_HOME_DIR" if [ "$LUAJIT" == "yes" ]; then if [ "$LUA" == "luajit" ]; then curl --location https://github.com/LuaJIT/LuaJIT/archive/v$LUAJIT_VERSION.tar.gz | tar xz; else git clone https://github.com/LuaJIT/LuaJIT.git $LUAJIT_BASE; fi cd $LUAJIT_BASE if [ "$LUA" == "luajit2.1" ]; then git checkout v2.1; # force the INSTALL_TNAME to be luajit perl -i -pe 's/INSTALL_TNAME=.+/INSTALL_TNAME= luajit/' Makefile fi make && make install PREFIX="$LUA_HOME_DIR" ln -s $LUA_HOME_DIR/bin/luajit $HOME/.lua/luajit ln -s $LUA_HOME_DIR/bin/luajit $HOME/.lua/lua; else if [ "$LUA" == "lua5.1" ]; then curl http://www.lua.org/ftp/lua-5.1.5.tar.gz | tar xz cd lua-5.1.5; elif [ "$LUA" == "lua5.2" ]; then curl http://www.lua.org/ftp/lua-5.2.4.tar.gz | tar xz cd lua-5.2.4; elif [ "$LUA" == "lua5.3" ]; then curl http://www.lua.org/ftp/lua-5.3.2.tar.gz | tar xz cd lua-5.3.2; fi # Build Lua without backwards compatibility for testing perl -i -pe 's/-DLUA_COMPAT_(ALL|5_2)//' src/Makefile make $PLATFORM make INSTALL_TOP="$LUA_HOME_DIR" install; ln -s $LUA_HOME_DIR/bin/lua $HOME/.lua/lua ln -s $LUA_HOME_DIR/bin/luac $HOME/.lua/luac; fi cd $TRAVIS_BUILD_DIR lua -v LUAROCKS_BASE=luarocks-$LUAROCKS curl --location http://luarocks.org/releases/$LUAROCKS_BASE.tar.gz | tar xz cd $LUAROCKS_BASE if [ "$LUA" == "luajit" ]; then ./configure --lua-suffix=jit --with-lua-include="$LUA_HOME_DIR/include/luajit-2.0" --prefix="$LR_HOME_DIR"; elif [ "$LUA" == "luajit2.0" ]; then ./configure --lua-suffix=jit --with-lua-include="$LUA_HOME_DIR/include/luajit-2.0" --prefix="$LR_HOME_DIR"; elif [ "$LUA" == "luajit2.1" ]; then ./configure --lua-suffix=jit --with-lua-include="$LUA_HOME_DIR/include/luajit-2.1" --prefix="$LR_HOME_DIR"; else ./configure --with-lua="$LUA_HOME_DIR" --prefix="$LR_HOME_DIR" fi make build && make install ln -s $LR_HOME_DIR/bin/luarocks $HOME/.lua/luarocks cd $TRAVIS_BUILD_DIR luarocks --version rm -rf $LUAROCKS_BASE if [ "$LUAJIT" == "yes" ]; then rm -rf $LUAJIT_BASE; elif [ "$LUA" == "lua5.1" ]; then rm -rf lua-5.1.5; elif [ "$LUA" == "lua5.2" ]; then rm -rf lua-5.2.4; elif [ "$LUA" == "lua5.3" ]; then rm -rf lua-5.3.2; fi luv-1.9.1-0/.ci/winmake.bat000066400000000000000000000317741274770366500153160ustar00rootroot00000000000000@ECHO OFF SETLOCAL ENABLEDELAYEDEXPANSION REM ***************************** REM * Customization section * REM ***************************** REM use the /help option for generic usage information REM Where is the source code located (the unpacked Lua source archive, toplevel dir) SET SOURCETREE=.\ REM set the toolchain to either MS or GCC (allcaps), leave blank to autodetect SET TOOLCHAIN= REM set the compatibility flags, defaults to empty for 5.1, -DLUA_COMPAT_ALL for 5.2, REM and -DLUA_COMPAT_5_2 for 5.3, which are the same as the unix make files REM This setting can be overridden with the --nocompat flag SET COMPATFLAG= REM ********************************** REM * Nothing to customize below * REM ********************************** SET BATCHNAME=%~n0 SET SOURCE=%SOURCETREE%src\ SET LUA_H=%SOURCE%lua.h SET CURDIR=%CD% REM the following line ends with a TAB. DO NOT REMOVE IT! SET TABCHAR= REM Define LF to contain a linefeed character set ^"LFCHAR=^ ^" The above empty line is critical. DO NOT REMOVE REM Supported toolchains (allcaps) SET TOOLCHAINS=MS GCC REM Commands which, if exiting without error, indicate presence of the toolchain SET CHECK_GCC=gcc --version SET CHECK_MS=cl REM ********************************** REM * Check for help request * REM ********************************** SET HELPCMDS=help -help --help /help ? -? /? for %%L in ("!LFCHAR!") do for /f %%a in ("!HELPCMDS: =%%~L!") do ( if "%%a"=="%~1" ( echo. echo Builds a standalone Lua installation. Supports Lua version 5.1, 5.2 and 5.3. echo Your compiler must be in the system path, and this "%BATCHNAME%.bat" file must be located echo in ".\etc\" in the unpacked Lua source archive. echo. echo USAGE etc\%BATCHNAME% [FLAG] [COMMAND] [...] echo ^(execute from the root of the unpacked archive^) echo. echo Commands; echo clean : cleans the source tree of build ^(intermediate^) files echo install [path] : installs the build results into "path" echo local : installs into ".\local\" in the unpacked Lua source structure echo [toolchain] : uses a specific toolchain to build. If not provided then supported echo toolchains will be tested and the first available will be picked. echo Supported toolchains are: "%TOOLCHAINS%" ^(must use ALLCAPS^) echo. echo Flags; echo --nocompat : Specifies that no compatibility flags should be set when building. echo If not specified, the default compatibility flags will be used. echo. echo Example use; echo set PATH=C:\path\to\your\compiler\;%%PATH%% echo etc\%BATCHNAME% clean echo etc\%BATCHNAME% echo etc\%BATCHNAME% --nocompat GCC echo etc\%BATCHNAME% install "C:\Program Files\Lua" echo. goto :EXITOK ) ) REM ********************************** REM * Check commandline * REM ********************************** SET CMDOK=FALSE if "%~1"=="" ( SET CMDOK=TRUE ) for %%a in (local install clean) do ( if "%%a"=="%~1" ( SET CMDOK=TRUE ) ) for %%a in (--nocompat) do ( if "%%a"=="%~1" ( SET NOCOMPAT=TRUE if "%~2"=="" ( SET CMDOK=TRUE ) SHIFT ) ) for %%a in (%TOOLCHAINS%) do ( if "%%a"=="%~1" ( SET CMDOK=TRUE SET TOOLCHAIN=%~1 ) ) if NOT %CMDOK%==TRUE ( echo. echo Unknown command or toolchain specified. goto :EXITERROR ) REM ************************************** REM * Check for cleaning * REM ************************************** if "%1"=="clean" ( if NOT [%2]==[] ( echo. echo ERROR: The clean command does not take extra parameters. ) else ( echo Cleaning... if exist "%SOURCE%*.exe" del "%SOURCE%*.exe" if exist "%SOURCE%*.dll" del "%SOURCE%*.dll" if exist "%SOURCE%*.o" del "%SOURCE%*.o" if exist "%SOURCE%*.a" del "%SOURCE%*.a" if exist "%SOURCE%*.obj" del "%SOURCE%*.obj" if exist "%SOURCE%*.manifest" del "%SOURCE%*.manifest" if exist "%SOURCE%*.lib" del "%SOURCE%*.lib" echo Done. ) goto :EXITOK ) REM ************************************************** REM * Fetch the Lua version from the source code * REM ************************************************** Echo. Echo Checking source code to extract Lua version... IF NOT EXIST %LUA_H% ( Echo Cannot locate Lua header file; %LUA_H% goto :EXITERROR ) findstr /R /C:"#define[ %TABCHAR%][ %TABCHAR%]*LUA_VERSION_MAJOR" %LUA_H% > NUL if NOT %ERRORLEVEL%==0 ( rem ECHO We've got a Lua version 5.1 rem findstr /R /C:"#define[ %TABCHAR%][ %TABCHAR%]*LUA_VERSION[ %TABCHAR%]" %LUA_H% SET LUA_VER=5.1 ) else ( rem ECHO We've got a Lua version 5.2+ rem findstr /R /C:"#define[ %TABCHAR%][ %TABCHAR%]*LUA_VERSION_MAJOR[ %TABCHAR%]" %LUA_H% rem findstr /R /C:"#define[ %TABCHAR%][ %TABCHAR%]*LUA_VERSION_MINOR[ %TABCHAR%]" %LUA_H% for /F "delims=" %%a in ('findstr /R /C:"#define[ %TABCHAR%][ %TABCHAR%]*LUA_VERSION_MAJOR[ %TABCHAR%]" %LUA_H%') do set LUA_MAJOR=%%a SET LUA_MAJOR=!LUA_MAJOR:#define=! SET LUA_MAJOR=!LUA_MAJOR:LUA_VERSION_MAJOR=! SET LUA_MAJOR=!LUA_MAJOR: =! SET LUA_MAJOR=!LUA_MAJOR:%TABCHAR%=! SET LUA_MAJOR=!LUA_MAJOR:"=! SET LUA_MAJOR=!LUA_MAJOR:~0,1! for /F "delims=" %%a in ('findstr /R /C:"#define[ %TABCHAR%][ %TABCHAR%]*LUA_VERSION_MINOR[ %TABCHAR%]" %LUA_H%') do set LUA_MINOR=%%a SET LUA_MINOR=!LUA_MINOR:#define=! SET LUA_MINOR=!LUA_MINOR:LUA_VERSION_MINOR=! SET LUA_MINOR=!LUA_MINOR: =! SET LUA_MINOR=!LUA_MINOR:%TABCHAR%=! SET LUA_MINOR=!LUA_MINOR:"=! SET LUA_MINOR=!LUA_MINOR:~0,1! SET LUA_VER=!LUA_MAJOR!.!LUA_MINOR! ) SET LUA_SVER=!LUA_VER:.=! Echo Lua version found: %LUA_VER% Echo. REM ************************************** REM * Set some Lua version specifics * REM ************************************** REM FILES_CORE; files for Lua core (+lauxlib, needed for Luac) REM FILES_LIB; files for Lua standard libraries REM FILES_DLL; vm files to be build with dll option REM FILES_OTH; vm files to be build without dll, for static linking if %LUA_SVER%==51 ( set FILES_CORE=lapi lcode ldebug ldo ldump lfunc lgc llex lmem lobject lopcodes lparser lstate lstring ltable ltm lundump lvm lzio lauxlib set FILES_LIB=lbaselib ldblib liolib lmathlib loslib ltablib lstrlib loadlib linit set FILES_DLL=lua set FILES_OTH=luac print set INSTALL_H=lauxlib.h lua.h luaconf.h lualib.h ..\etc\lua.hpp ) if %LUA_SVER%==52 ( set FILES_CORE=lapi lcode lctype ldebug ldo ldump lfunc lgc llex lmem lobject lopcodes lparser lstate lstring ltable ltm lundump lvm lzio lauxlib set FILES_LIB=lbaselib lbitlib lcorolib ldblib liolib lmathlib loslib lstrlib ltablib loadlib linit set FILES_DLL=lua set FILES_OTH=luac set INSTALL_H=lauxlib.h lua.h lua.hpp luaconf.h lualib.h if "%COMPATFLAG%"=="" ( set COMPATFLAG=-DLUA_COMPAT_ALL ) ) if %LUA_SVER%==53 ( set FILES_CORE=lapi lcode lctype ldebug ldo ldump lfunc lgc llex lmem lobject lopcodes lparser lstate lstring ltable ltm lundump lvm lzio lauxlib set FILES_LIB=lbaselib lbitlib lcorolib ldblib liolib lmathlib loslib lstrlib ltablib lutf8lib loadlib linit set FILES_DLL=lua set FILES_OTH=luac set INSTALL_H=lauxlib.h lua.h lua.hpp luaconf.h lualib.h if "%COMPATFLAG%"=="" ( set COMPATFLAG=-DLUA_COMPAT_5_2 ) ) if "%NOCOMPAT%"=="TRUE" ( set COMPATFLAG= ) SET FILES_BASE=%FILES_DLL% %FILES_CORE% %FILES_LIB% if "%FILES_BASE%"=="" ( Echo Unknown Lua version; %LUA_VER% goto :EXITERROR ) REM ********************************* REM * Check available toolchain * REM ********************************* if [%TOOLCHAIN%]==[] ( Echo Testing for MS... %CHECK_MS% IF !ERRORLEVEL!==0 SET TOOLCHAIN=MS ) if [%TOOLCHAIN%]==[] ( Echo Testing for GCC... %CHECK_GCC% IF !ERRORLEVEL!==0 SET TOOLCHAIN=GCC ) if [%TOOLCHAIN%]==[] ( Echo No supported toolchain found ^(please make sure it is in the system path^) goto :EXITERROR ) REM *************************** REM * Configure toolchain * REM *************************** if %TOOLCHAIN%==GCC ( echo Using GCC toolchain... SET OBJEXT=o SET LIBFILE=liblua%LUA_SVER%.a ) if %TOOLCHAIN%==MS ( echo Using Microsoft toolchain... SET OBJEXT=obj SET LIBFILE=lua%LUA_SVER%.lib ) echo. REM ************************************** REM * Check for installing * REM ************************************** if "%1"=="install" ( if "%~2"=="" ( echo. echo ERROR: The install command requires a path where to install to. goto :EXITERROR ) SET TARGETPATH=%~2 ) if "%1"=="local" ( if NOT "%~2"=="" ( echo. echo ERROR: The local command does not take extra parameters. goto :EXITERROR ) SET TARGETPATH=%SOURCETREE%local ) if NOT "%TARGETPATH%"=="" ( mkdir "%TARGETPATH%\bin" mkdir "%TARGETPATH%\include" mkdir "%TARGETPATH%\lib\lua\%LUA_VER%" mkdir "%TARGETPATH%\man\man1" mkdir "%TARGETPATH%\share\lua\%LUA_VER%" copy "%SOURCE%lua.exe" "%TARGETPATH%\bin" copy "%SOURCE%luac.exe" "%TARGETPATH%\bin" copy "%SOURCE%lua%LUA_SVER%.dll" "%TARGETPATH%\bin" for %%a in (%INSTALL_H%) do ( copy "%SOURCE%%%a" "%TARGETPATH%\include" ) copy "%SOURCE%%LIBFILE%" "%TARGETPATH%\lib" copy "%SOURCETREE%doc\lua.1" "%TARGETPATH%\man\man1" copy "%SOURCETREE%doc\luac.1" "%TARGETPATH%\man\man1" echo Installation completed in "%TARGETPATH%". goto :EXITOK ) REM *********************** REM * Compile sources * REM *********************** goto :after_compile_function :compile_function REM Params: %1 is filelist (must be quoted) REM Return: same list, with the object file extension included, will be stored in global OBJLIST for %%a in (%~1) do ( SET FILENAME=%%a if %TOOLCHAIN%==GCC ( SET COMPCMD=gcc -O2 -Wall !EXTRAFLAG! !COMPATFLAG! -c -o !FILENAME!.%OBJEXT% !FILENAME!.c ) if %TOOLCHAIN%==MS ( SET COMPCMD=cl /nologo /MD /O2 /W3 /c /D_CRT_SECURE_NO_DEPRECATE !COMPATFLAG! !EXTRAFLAG! !FILENAME!.c ) echo !COMPCMD! !COMPCMD! SET OBJLIST=!OBJLIST! !FILENAME!.%OBJEXT% ) goto :eof :after_compile_function CD %SOURCE% REM Traverse the 4 lists of source files for %%b in (CORE LIB DLL OTH) do ( SET LTYPE=%%b SET OBJLIST= if !LTYPE!==OTH ( REM OTH is the only list of files build without DLL option SET EXTRAFLAG= ) else ( SET EXTRAFLAG=-DLUA_BUILD_AS_DLL ) if !LTYPE!==CORE SET FILELIST=%FILES_CORE% if !LTYPE!==LIB SET FILELIST=%FILES_LIB% if !LTYPE!==DLL SET FILELIST=%FILES_DLL% if !LTYPE!==OTH SET FILELIST=%FILES_OTH% echo Now compiling !LTYPE! file set... call:compile_function "!FILELIST!" if !LTYPE!==CORE SET FILES_CORE_O=!OBJLIST! if !LTYPE!==LIB SET FILES_LIB_O=!OBJLIST! if !LTYPE!==DLL SET FILES_DLL_O=!OBJLIST! if !LTYPE!==OTH SET FILES_OTH_O=!OBJLIST! ) REM **************************** REM * Link GCC based files * REM **************************** if %TOOLCHAIN%==GCC ( REM Link the LuaXX.dll file SET LINKCMD=gcc -shared -o lua%LUA_SVER%.dll %FILES_CORE_O% %FILES_LIB_O% echo !LINKCMD! !LINKCMD! REM strip from LuaXX.dll SET RANCMD=strip --strip-unneeded lua%LUA_SVER%.dll echo !RANCMD! !RANCMD! REM Link the Lua.exe file SET LINKCMD=gcc -o lua.exe -s lua.%OBJEXT% lua%LUA_SVER%.dll -lm echo !LINKCMD! !LINKCMD! REM create lib archive SET LIBCMD=ar rcu liblua%LUA_SVER%.a %FILES_CORE_O% %FILES_LIB_O% echo !LIBCMD! !LIBCMD! REM Speedup index using ranlib SET RANCMD=ranlib liblua%LUA_SVER%.a echo !RANCMD! !RANCMD! REM Link Luac.exe file SET LINKCMD=gcc -o luac.exe %FILES_OTH_O% liblua%LUA_SVER%.a -lm echo !LINKCMD! !LINKCMD! ) REM **************************** REM * Link MS based files * REM **************************** if %TOOLCHAIN%==MS ( REM Link the LuaXX.dll file, and LuaXX.obj SET LINKCMD=link /nologo /DLL /out:lua%LUA_SVER%.dll %FILES_CORE_O% %FILES_LIB_O% echo !LINKCMD! !LINKCMD! REM handle dll manifest if exist lua%LUA_SVER%.dll.manifest ( SET MANICMD=mt /nologo -manifest lua%LUA_SVER%.dll.manifest -outputresource:lua%LUA_SVER%.dll;2 echo !MANICMD! !MANICMD! ) REM Link Lua.exe SET LINKCMD=link /nologo /out:lua.exe lua.%OBJEXT% lua%LUA_SVER%.lib echo !LINKCMD! !LINKCMD! REM handle manifest if exist lua.exe.manifest ( SET MANICMD=mt /nologo -manifest lua.exe.manifest -outputresource:lua.exe echo !MANICMD! !MANICMD! ) REM Link Luac.exe SET LINKCMD=link /nologo /out:luac.exe %FILES_OTH_O% %FILES_CORE_O% echo !LINKCMD! !LINKCMD! REM handle manifest if exist luac.exe.manifest ( SET MANICMD=mt /nologo -manifest luac.exe.manifest -outputresource:luac.exe echo !MANICMD! !MANICMD! ) ) CD %CURDIR% REM **************************** REM * Finished building * REM **************************** echo. echo Build completed. goto :EXITOK :EXITOK exit /B 0 :EXITERROR echo For help try; etc\%BATCHNAME% /help exit /B 1 luv-1.9.1-0/.gitignore000066400000000000000000000001461274770366500144770ustar00rootroot00000000000000build libluv.a libluv.so luv.so luv.dll luajit.exe luv-*.tar.gz luv-*.src.rock luv-*/ build.luarocks/ luv-1.9.1-0/.gitmodules000066400000000000000000000003531274770366500146640ustar00rootroot00000000000000[submodule "libuv"] path = deps/libuv url = https://github.com/libuv/libuv.git [submodule "luajit"] path = deps/luajit url = https://github.com/LuaJIT/LuaJIT.git [submodule "lua"] path = deps/lua url = https://github.com/lua/lua luv-1.9.1-0/.travis.yml000066400000000000000000000016751274770366500146300ustar00rootroot00000000000000language: c sudo: false addons: apt: sources: - kalakris-cmake packages: - cmake env: global: - LUAROCKS=2.3.0 matrix: - WITH_LUA_ENGINE=Lua LUA=lua5.3 - WITH_LUA_ENGINE=LuaJIT LUA=luajit2.1 - PROCESS_CLEANUP_TEST=1 LUA=lua5.2 os: - linux - osx before_install: - git submodule update --init --recursive - git submodule update --recursive script: - if [ "x$PROCESS_CLEANUP_TEST" = "x" ]; then make && make test; else ./tests/test-sigchld-after-lua_close.sh; fi # Test rock installation - source .ci/setenv_lua.sh - luarocks make - test $PWD = `lua -e "print(require'luv'.cwd())"` - luarocks remove luv # Test the alternate rockspec - mkdir build/lib - cp build/libuv.a build/lib - cp -a deps/libuv/include build - luarocks make rockspecs/$(ls rockspecs) LIBUV_DIR=build - test $PWD = `lua -e "print(require'luv'.cwd())"` notifications: email: true irc: "irc.freenode.org#luvit" luv-1.9.1-0/CMakeLists.txt000066400000000000000000000135421274770366500152530ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.8) if(POLICY CMP0053) cmake_policy(SET CMP0053 NEW) # faster evaluation of variable references endif() project (luv C ASM) set(LUV_VERSION_MAJOR 1) set(LUV_VERSION_MINOR 9) set(LUV_VERSION_PATCH 1) set(LUV_VERSION ${LUV_VERSION_MAJOR}.${LUV_VERSION_MINOR}.${LUV_VERSION_PATCH}) option(BUILD_MODULE "Build as module" ON) option(BUILD_SHARED_LIBS "Build shared library" OFF) option(WITH_SHARED_LIBUV "Link to a shared libuv library instead of static linking" OFF) if (MINGW) add_definitions(-D_WIN32_WINNT=0x0600) endif (MINGW) if (NOT WITH_LUA_ENGINE) set(WITH_LUA_ENGINE "LuaJIT" CACHE STRING "Link to LuaJIT or PUC Lua" FORCE) set_property(CACHE WITH_LUA_ENGINE PROPERTY STRINGS "Lua;LuaJIT") endif (NOT WITH_LUA_ENGINE) if (NOT LUA_BUILD_TYPE) set(LUA_BUILD_TYPE "Static" CACHE STRING "Build Lua/LuaJIT as static, dynamic libary, or use system one" FORCE) set_property(CACHE LUA_BUILD_TYPE PROPERTY STRINGS "Static;Dynamic;System") endif (NOT LUA_BUILD_TYPE) if (WITH_LUA_ENGINE STREQUAL Lua) if (NOT WIN32) add_definitions(-DLUA_USE_DLOPEN) endif (NOT WIN32) set(USE_LUAJIT OFF) else () set(USE_LUAJIT ON) endif () set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") if (WITH_SHARED_LIBUV) find_package(Libuv) if (LIBUV_FOUND) include_directories(${LIBUV_INCLUDE_DIR}) endif (LIBUV_FOUND) else (WITH_SHARED_LIBUV) include(deps/uv.cmake) if (BUILD_MODULE) add_definitions( -DBUILDING_UV_SHARED ) endif (BUILD_MODULE) set(LIBUV_LIBRARIES uv) endif (WITH_SHARED_LIBUV) if (LUA) MESSAGE(STATUS "Lua: using information from luarocks") MESSAGE(STATUS "LUA_LIBDIR: " ${LUA_LIBDIR}) MESSAGE(STATUS "LUA_INCDIR: " ${LUA_INCDIR}) MESSAGE(STATUS "LUA: " ${LUA}) SET(LUA_EXECUTABLE "${LUA}") SET(LUA_INCLUDE_DIR "${LUA_INCDIR}") SET(LUA_PACKAGE_PATH "${LUADIR}") SET(LUA_PACKAGE_CPATH "${LIBDIR}") SET(INSTALL_LIB_DIR ${LIBDIR}) GET_FILENAME_COMPONENT(LUA_EXEC_NAME ${LUA_EXECUTABLE} NAME_WE) IF(LUA_EXEC_NAME STREQUAL "luajit") FIND_LIBRARY(LUA_LIBRARIES NAMES luajit libluajit PATHS ${LUA_LIBDIR} NO_DEFAULT_PATH) ELSEIF(LUA_EXEC_NAME STREQUAL "lua") FIND_LIBRARY(LUA_LIBRARIES NAMES lua lua53 lua52 lua51 liblua liblua53 liblua52 liblua51 PATHS ${LUA_LIBDIR} NO_DEFAULT_PATH) ENDIF() MESSAGE(STATUS "Lua library: ${LUA_LIBRARIES}") include_directories(${LUA_INCLUDE_DIR}) else (LUA) if (LUA_BUILD_TYPE STREQUAL System) if (USE_LUAJIT) find_package(LuaJIT) if (LUAJIT_FOUND) include_directories(${LUAJIT_INCLUDE_DIR}) link_directories(${LUAJIT_LIBRARIES}) endif (LUAJIT_FOUND) else (USE_LUAJIT) find_package(Lua) if (LUA_FOUND) include_directories(${LUA_INCLUDE_DIR}) endif (LUA_FOUND) endif (USE_LUAJIT) else (LUA_BUILD_TYPE STREQUAL System) if (LUA_BUILD_TYPE STREQUAL Static) SET(WITH_SHARED_LUA OFF) else (LUA_BUILD_TYPE STREQUAL Static) SET(WITH_SHARED_LUA ON) endif (LUA_BUILD_TYPE STREQUAL Static) if (USE_LUAJIT) include(deps/luajit.cmake) include_directories(deps/luajit/src) set(LUAJIT_LIBRARIES luajit-5.1) else(USE_LUAJIT) include(deps/lua.cmake) include_directories(deps/lua/src) endif (USE_LUAJIT) endif (LUA_BUILD_TYPE STREQUAL System) endif (LUA) if (BUILD_MODULE) add_library(luv MODULE src/luv.c) set_target_properties(luv PROPERTIES PREFIX "") else (BUILD_MODULE) add_library(luv src/luv.c) if (BUILD_SHARED_LIBS) set_target_properties(luv PROPERTIES VERSION ${LUV_VERSION} SOVERSION ${LUV_VERSION_MAJOR}) endif (BUILD_SHARED_LIBS) endif (BUILD_MODULE) if(APPLE) set(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "${CMAKE_SHARED_MODULE_CREATE_C_FLAGS} -flat_namespace -undefined suppress" ) # execute_process(COMMAND which luajit OUTPUT_VARIABLE LUAJIT) # set(CMAKE_SHARED_MODULE_CREATE_C_FLAGS # "${CMAKE_SHARED_MODULE_CREATE_C_FLAGS} -bundle_loader ${LUAJIT}" # ) endif() if(WIN32) add_definitions(-DLUA_BUILD_AS_DLL -DLUA_LIB) if (LUA) target_link_libraries(luv ${LIBUV_LIBRARIES} ${LUA_LIBRARIES}) else (LUA) if (USE_LUAJIT) target_link_libraries(luv ${LIBUV_LIBRARIES} ${LUAJIT_LIBRARIES}) else (USE_LUAJIT) if (LUA_BUILD_TYPE STREQUAL System) target_link_libraries(luv ${LIBUV_LIBRARIES} ${LUA_LIBRARIES}) else (LUA_BUILD_TYPE STREQUAL System) target_link_libraries(luv ${LIBUV_LIBRARIES} lualib) endif (LUA_BUILD_TYPE STREQUAL System) endif (USE_LUAJIT) endif (LUA) # replace /MD to /MT to avoid link msvcr*.dll set(CompilerFlags CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO CMAKE_C_FLAGS_RELEASE) foreach(CompilerFlag ${CompilerFlags}) string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}") endforeach() elseif("${CMAKE_SYSTEM_NAME}" MATCHES "Linux") target_link_libraries(luv ${LIBUV_LIBRARIES} rt) else() target_link_libraries(luv ${LIBUV_LIBRARIES}) endif() if (NOT LUA) if (BUILD_MODULE) if (WIN32) set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") else (WIN32) set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib/lua/${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}") endif (WIN32) else (BUILD_MODULE) set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation directory for libraries") set(INSTALL_INC_DIR "${CMAKE_INSTALL_PREFIX}/include/luv" CACHE PATH "Installation directory for headers") endif (BUILD_MODULE) endif () if (CMAKE_INSTALL_PREFIX) install(TARGETS luv ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" LIBRARY DESTINATION "${INSTALL_LIB_DIR}" ) if (NOT BUILD_MODULE) install( FILES src/luv.h src/util.h src/lhandle.h src/lreq.h DESTINATION "${INSTALL_INC_DIR}" ) endif (NOT BUILD_MODULE) endif (CMAKE_INSTALL_PREFIX) luv-1.9.1-0/LICENSE.txt000066400000000000000000000261361274770366500143410ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. luv-1.9.1-0/Makefile000066400000000000000000000027141274770366500141520ustar00rootroot00000000000000LUV_TAG=$(shell git describe --tags) ifdef WITHOUT_AMALG CMAKE_OPTIONS+= -DWITH_AMALG=OFF endif BUILD_MODULE ?= ON BUILD_SHARED_LIBS ?= OFF WITH_SHARED_LIBUV ?= OFF WITH_LUA_ENGINE ?= LuaJIT LUA_BUILD_TYPE ?= Static ifeq ($(WITH_LUA_ENGINE), LuaJIT) LUABIN=build/luajit else LUABIN=build/lua endif CMAKE_OPTIONS += \ -DBUILD_MODULE=$(BUILD_MODULE) \ -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) \ -DWITH_SHARED_LIBUV=$(WITH_SHARED_LIBUV) \ -DWITH_LUA_ENGINE=$(WITH_LUA_ENGINE) \ -DLUA_BUILD_TYPE=$(LUA_BUILD_TYPE) \ all: luv deps/libuv/include: git submodule update --init deps/libuv deps/luajit/src: git submodule update --init deps/luajit build/Makefile: deps/libuv/include deps/luajit/src cmake -H. -Bbuild ${CMAKE_OPTIONS} -DWITH_AMALG=OFF luv: build/Makefile cmake --build build --config Debug ln -sf build/luv.so clean: rm -rf build luv.so test: luv ${LUABIN} tests/run.lua reset: git submodule update --init --recursive && \ git clean -f -d && \ git checkout . publish-luarocks: rm -rf luv-${LUV_TAG} mkdir -p luv-${LUV_TAG}/deps cp -r src cmake CMakeLists.txt LICENSE.txt README.md docs.md luv-${LUV_TAG}/ cp -r deps/libuv deps/*.cmake deps/lua_one.c luv-${LUV_TAG}/deps/ COPYFILE_DISABLE=true tar -czvf luv-${LUV_TAG}.tar.gz luv-${LUV_TAG} github-release upload --user luvit --repo luv --tag ${LUV_TAG} \ --file luv-${LUV_TAG}.tar.gz --name luv-${LUV_TAG}.tar.gz luarocks upload luv-${LUV_TAG}.rockspec --api-key=${LUAROCKS_TOKEN} luv-1.9.1-0/README.md000066400000000000000000000130511274770366500137650ustar00rootroot00000000000000luv === [![Linux Build Status](https://travis-ci.org/luvit/luv.svg?branch=master)](https://travis-ci.org/luvit/luv) [![Windows Build status](https://ci.appveyor.com/api/projects/status/uo1qhdcc0vcqsiok/branch/master?svg=true)](https://ci.appveyor.com/project/racker-buildbot/luv/branch/master) [libuv](https://github.com/joyent/libuv) bindings for [luajit](http://luajit.org/) and [lua](http://www.lua.org/) [5.1](http://www.lua.org/manual/5.1/manual.html)/ [5.2](http://www.lua.org/manual/5.2/manual.html)/ [5.3](http://www.lua.org/manual/5.3/manual.html). This library makes libuv available to lua scripts. It was made for the [luvit](http://luvit.io/) project but should usable from nearly any lua project. The library can be used by multiple threads at once. Each thread is assumed to load the library from a different `lua_State`. Luv will create a unique `uv_loop_t` for each state. You can't share uv handles between states/loops. The best docs currently are the [libuv docs](http://docs.libuv.org/) themselves. Hopfully soon we'll have a copy locally tailored for lua. ```lua local uv = require('luv') -- Create a handle to a uv_timer_t local timer = uv.new_timer() -- This will wait 1000ms and then continue inside the callback timer:start(1000, 0, function () -- timer here is the value we passed in before from new_timer. print ("Awake!") -- You must always close your uv handles or you'll leak memory -- We can't depend on the GC since it doesn't know enough about libuv. timer:close() end) print("Sleeping"); -- uv.run will block and wait for all events to run. -- When there are no longer any active handles, it will return uv.run() ``` Here is an example of an TCP echo server ```lua local uv = require('luv') local function create_server(host, port, on_connection) local server = uv.new_tcp() server:bind(host, port) server:listen(128, function(err) -- Make sure there was no problem setting up listen assert(not err, err) -- Accept the client local client = uv.new_tcp() server:accept(client) on_connection(client) end) return server end local server = create_server("0.0.0.0", 0, function (client) client:read_start(function (err, chunk) -- Crash on errors assert(not err, err) if chunk then -- Echo anything heard client:write(chunk) else -- When the stream ends, close the socket client:close() end end) end) print("TCP Echo serverr listening on port " .. server:getsockname().port) uv.run() ``` More examples can be found in the [examples](examples) and [tests](tests) folders. ## Building From Source To build, first install your compiler tools. ### Get a Compiler On linux this probably means `gcc` and `make`. On Ubuntu, the `build-essential` package is good for this. On OSX, you probably want XCode which comes with `clang` and `make` and friends. For windows the free Visual Studio Express works. If you get the 2013 edition, make sure to get the `Windows Deskop` edition. The `Windows` version doesn't include a working C compiler. Make sure to run all of setup including getting a free license. ### Install CMake Now install Cmake. The version in `brew` on OSX or most Linux package managers is good. The version on Travis CI is too old and so I use a PPA there. On windows use the installer and make sure to add cmake to your command prompt path. ### Install Git If you haven't already, install git and make sure it's in your path. This comes with XCode on OSX. On Linux it's in your package manager. For windows, use the installer at . Make sure it's available to your windows command prompt. ### Clone the Code Now open a terminal and clone the code. For windows I recommend the special developer command prompt that came with Visual Studio. ``` git clone https://github.com/luvit/luv.git --recursive cd luv ``` ### Build the Code and Test On windows I wrote a small batch file that runs the correct cmake commands and copies the output files for easy access. ``` C:\Code\luv> msvcbuild.bat C:\Code\luv> luajit tests\run.lua ``` On unix systems, use the Makefile. ``` ~/Code/luv> make test ``` This will build luv as a module library. Module libraries are plugins that are not linked into other targets. #### Build with PUC Lua 5.3 By default luv is linked with LuaJIT 2.0.4. If you rather like to link luv with PUC Lua 5.3 you can run make with: ``` ~/Code/luv> WITH_LUA_ENGINE=Lua make ``` #### Build as static library If you want to build luv as a static library run make with: ``` ~/Code/luv> BUILD_MODULE=OFF make ``` This will create a static library `libluv.a`. #### Build as shared library If you want to build luv as a shared library run make with: ``` ~/Code/luv> BUILD_MODULE=OFF BUILD_SHARED_LIBS=ON make ``` This will create a shared library `libluv.so`. #### Build with shared libraries By default the build system will build luv with the supplied dependencies. These are: * libuv * LuaJIT or Lua However, if your target system has already one or more of these dependencies installed you can link `luv` against them. ##### Linking with shared libuv The default shared library name for libuv is `libuv`. To link against it use: ``` ~/Code/luv> WITH_SHARED_LIBUV=ON make ``` ##### Linking with shared LuaJIT The default shared library name for LuaJIT is `libluajit-5.1`. To link against it use: ``` ~/Code/luv> LUA_BUILD_TYPE=System make ``` ##### Linking with shared Lua 5.x The default shared library name for Lua 5.x is `liblua5.x`. To link against it use: ``` ~/Code/luv> LUA_BUILD_TYPE=System WITH_LUA_ENGINE=Lua make ``` luv-1.9.1-0/appveyor.yml000066400000000000000000000022621274770366500151000ustar00rootroot00000000000000os: Visual Studio 2015 # Test with the latest two releases of MSVC configuration: - 2015 - 2013 # Test with the latest Lua and LuaJIT versions environment: LUAROCKS_VER: 2.3.0 matrix: - LUA_VER: 5.3.2 NOCOMPAT: true # with compatibility flags disabled. - LJ_VER: 2.1 platform: - x86 - x64 matrix: fast_finish: true cache: - c:\lua -> appveyor.yml - c:\external -> appveyor.yml install: - git submodule update --init build_script: - msvcbuild.bat - luajit.exe tests\run.lua # Test rock installation - call .ci\set_compiler_env.bat - call .ci\install.bat - luarocks make - ps: if("$(Get-Location)" -eq $(lua -e "print(require'luv'.cwd())")) { "LuaRocks test OK" } else { "LuaRocks test failed"; exit 1 } - luarocks remove luv # Test the alternate rockspec - mkdir build\lib - cp build\Release\uv.lib build\lib - cp -a deps\libuv\include build - ps: luarocks make rockspecs\$(ls rockspecs) LIBUV_DIR=build CFLAGS="/nologo /MT /O2" - ps: if("$(Get-Location)" -eq $(lua -e "print(require'luv'.cwd())")) { "LuaRocks test OK" } else { "LuaRocks test failed"; exit 1 } - luarocks remove luv artifacts: - path: luv.dll - path: luajit.exe luv-1.9.1-0/bump.sh000077500000000000000000000006321274770366500140110ustar00rootroot00000000000000#!/bin/sh version=$1 if [ -z "$version" ]; then echo "must specify a version" >&2 exit 1 fi script="/^version/s@\"[^\"]\\+\"@\"${version}\"@" sed -e "${script}" -i luv-*.rockspec sed -e "${script}" -i rockspecs/luv-*.rockspec git mv luv-*.rockspec luv-${version}.rockspec git mv rockspecs/luv-*.rockspec rockspecs/luv-${version}.rockspec git add luv-${version}.rockspec rockspecs/luv-${version}.rockspec luv-1.9.1-0/cmake/000077500000000000000000000000001274770366500135665ustar00rootroot00000000000000luv-1.9.1-0/cmake/Modules/000077500000000000000000000000001274770366500151765ustar00rootroot00000000000000luv-1.9.1-0/cmake/Modules/FindLibuv.cmake000066400000000000000000000024441274770366500200660ustar00rootroot00000000000000#============================================================================= # Copyright 2016 The Luvit Authors. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. #============================================================================= # Locate libuv library # This module defines # LIBUV_FOUND, if false, do not try to link to libuv # LIBUV_LIBRARIES # LIBUV_INCLUDE_DIR, where to find uv.h FIND_PATH(LIBUV_INCLUDE_DIR NAMES uv.h) FIND_LIBRARY(LIBUV_LIBRARIES NAMES uv libuv) if(WIN32) list(APPEND LIBUV_LIBRARIES iphlpapi) list(APPEND LIBUV_LIBRARIES psapi) list(APPEND LIBUV_LIBRARIES userenv) list(APPEND LIBUV_LIBRARIES ws2_32) endif() INCLUDE(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBUV DEFAULT_MSG LIBUV_LIBRARIES LIBUV_INCLUDE_DIR) luv-1.9.1-0/cmake/Modules/FindLuaJIT.cmake000066400000000000000000000057351274770366500201030ustar00rootroot00000000000000#============================================================================= # Copyright 2007-2009 Kitware, Inc. # Copyright 2013 Rolf Eike Beer # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. # # This software is distributed WITHOUT ANY WARRANTY; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the License for more information. #============================================================================= # We use code from the CMake project to detect the Lua version. # Locate LuaJIT library # This module defines # LUAJIT_FOUND, if false, do not try to link to Lua JIT # LUAJIT_LIBRARIES # LUAJIT_INCLUDE_DIR, where to find lua.h # # Additionally it defines the Lua API/ABI version: # LUA_VERSION_STRING - the version of Lua found # LUA_VERSION_MAJOR - the major version of Lua # LUA_VERSION_MINOR - the minor version of Lua # LUA_VERSION_PATCH - the patch version of Lua FIND_PATH(LUAJIT_INCLUDE_DIR NAMES lua.h PATH_SUFFIXES luajit-2.0) FIND_LIBRARY(LUAJIT_LIBRARIES NAMES luajit-5.1 luajit) if (LUAJIT_INCLUDE_DIR AND EXISTS "${LUAJIT_INCLUDE_DIR}/lua.h") # At least 5.[012] have different ways to express the version # so all of them need to be tested. Lua 5.2 defines LUA_VERSION # and LUA_RELEASE as joined by the C preprocessor, so avoid those. file(STRINGS "${LUAJIT_INCLUDE_DIR}/lua.h" lua_version_strings REGEX "^#define[ \t]+LUA_(RELEASE[ \t]+\"Lua [0-9]|VERSION([ \t]+\"Lua [0-9]|_[MR])).*") string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MAJOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_MAJOR ";${lua_version_strings};") if (LUA_VERSION_MAJOR MATCHES "^[0-9]+$") string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MINOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_MINOR ";${lua_version_strings};") string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_RELEASE[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_PATCH ";${lua_version_strings};") set(LUA_VERSION_STRING "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}.${LUA_VERSION_PATCH}") else () string(REGEX REPLACE ".*;#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" LUA_VERSION_STRING ";${lua_version_strings};") if (NOT LUA_VERSION_STRING MATCHES "^[0-9.]+$") string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" LUA_VERSION_STRING ";${lua_version_strings};") endif () string(REGEX REPLACE "^([0-9]+)\\.[0-9.]*$" "\\1" LUA_VERSION_MAJOR "${LUA_VERSION_STRING}") string(REGEX REPLACE "^[0-9]+\\.([0-9]+)[0-9.]*$" "\\1" LUA_VERSION_MINOR "${LUA_VERSION_STRING}") string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]).*" "\\1" LUA_VERSION_PATCH "${LUA_VERSION_STRING}") endif () unset(lua_version_strings) endif() INCLUDE(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(LUAJIT DEFAULT_MSG LUAJIT_LIBRARIES LUAJIT_INCLUDE_DIR) luv-1.9.1-0/deps/000077500000000000000000000000001274770366500134415ustar00rootroot00000000000000luv-1.9.1-0/deps/libuv/000077500000000000000000000000001274770366500145625ustar00rootroot00000000000000luv-1.9.1-0/deps/lua/000077500000000000000000000000001274770366500142225ustar00rootroot00000000000000luv-1.9.1-0/deps/lua.cmake000066400000000000000000000113261274770366500152270ustar00rootroot00000000000000# Modfied from luajit.cmake # Added LUA_ADD_EXECUTABLE Ryan Phillips # This CMakeLists.txt has been first taken from LuaDist # Copyright (C) 2007-2011 LuaDist. # Created by Peter Drahoš # Redistribution and use of this file is allowed according to the terms of the MIT license. # Debugged and (now seriously) modified by Ronan Collobert, for Torch7 #project(Lua53 C) SET(LUA_DIR ${CMAKE_CURRENT_LIST_DIR}/lua CACHE PATH "location of lua sources") SET(CMAKE_REQUIRED_INCLUDES ${LUA_DIR} ${LUA_DIR}/src ${CMAKE_CURRENT_BINARY_DIR} ) OPTION(WITH_AMALG "Build eveything in one shot (needs memory)" ON) # Ugly warnings IF(MSVC) ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS) ENDIF() # Various includes INCLUDE(CheckLibraryExists) INCLUDE(CheckFunctionExists) INCLUDE(CheckCSourceCompiles) INCLUDE(CheckTypeSize) CHECK_TYPE_SIZE("void*" SIZEOF_VOID_P) IF(SIZEOF_VOID_P EQUAL 8) ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE) ENDIF() IF(NOT WIN32) FIND_LIBRARY(DL_LIBRARY "dl") IF(DL_LIBRARY) SET(CMAKE_REQUIRED_LIBRARIES ${DL_LIBRARY}) LIST(APPEND LIBS ${DL_LIBRARY}) ENDIF(DL_LIBRARY) CHECK_FUNCTION_EXISTS(dlopen LUA_USE_DLOPEN) IF(NOT LUA_USE_DLOPEN) MESSAGE(FATAL_ERROR "Cannot compile a useful lua. Function dlopen() seems not to be supported on your platform. Apparently you are not on a Windows platform as well. So lua has no way to deal with shared libraries!") ENDIF(NOT LUA_USE_DLOPEN) ENDIF(NOT WIN32) check_library_exists(m sin "" LUA_USE_LIBM) if ( LUA_USE_LIBM ) list ( APPEND LIBS m ) endif () ## SOURCES SET(SRC_LUALIB ${LUA_DIR}/src/lbaselib.c ${LUA_DIR}/src/lcorolib.c ${LUA_DIR}/src/ldblib.c ${LUA_DIR}/src/liolib.c ${LUA_DIR}/src/lmathlib.c ${LUA_DIR}/src/loadlib.c ${LUA_DIR}/src/loslib.c ${LUA_DIR}/src/lstrlib.c ${LUA_DIR}/src/ltablib.c ${LUA_DIR}/src/lutf8lib.c) SET(SRC_LUACORE ${LUA_DIR}/src/lauxlib.c ${LUA_DIR}/src/lapi.c ${LUA_DIR}/src/lcode.c ${LUA_DIR}/src/lctype.c ${LUA_DIR}/src/ldebug.c ${LUA_DIR}/src/ldo.c ${LUA_DIR}/src/ldump.c ${LUA_DIR}/src/lfunc.c ${LUA_DIR}/src/lgc.c ${LUA_DIR}/src/linit.c ${LUA_DIR}/src/llex.c ${LUA_DIR}/src/lmem.c ${LUA_DIR}/src/lobject.c ${LUA_DIR}/src/lopcodes.c ${LUA_DIR}/src/lparser.c ${LUA_DIR}/src/lstate.c ${LUA_DIR}/src/lstring.c ${LUA_DIR}/src/ltable.c ${LUA_DIR}/src/ltm.c ${LUA_DIR}/src/lundump.c ${LUA_DIR}/src/lvm.c ${LUA_DIR}/src/lzio.c ${SRC_LUALIB}) ## GENERATE IF(WITH_SHARED_LUA) IF(WITH_AMALG) add_library(lualib SHARED ${LUA_DIR}/../lua_one.c) ELSE() add_library(lualib SHARED ${SRC_LUACORE}) ENDIF() ELSE() IF(WITH_AMALG) add_library(lualib STATIC ${LUA_DIR}/../lua_one.c ) ELSE() add_library(lualib STATIC ${SRC_LUACORE} ) ENDIF() set_target_properties(lualib PROPERTIES PREFIX "lib" IMPORT_PREFIX "lib") ENDIF() target_link_libraries (lualib ${LIBS} ) set_target_properties (lualib PROPERTIES OUTPUT_NAME "lua53") add_executable(lua ${LUA_DIR}/src/lua.c) IF(WIN32) target_link_libraries(lua lualib) ELSE() target_link_libraries(lua lualib ${LIBS}) SET_TARGET_PROPERTIES(lua PROPERTIES ENABLE_EXPORTS ON) ENDIF(WIN32) MACRO(LUA_add_custom_commands luajit_target) SET(target_srcs "") FOREACH(file ${ARGN}) IF(${file} MATCHES ".*\\.lua$") set(file "${CMAKE_CURRENT_SOURCE_DIR}/${file}") set(source_file ${file}) string(LENGTH ${CMAKE_SOURCE_DIR} _luajit_source_dir_length) string(LENGTH ${file} _luajit_file_length) math(EXPR _begin "${_luajit_source_dir_length} + 1") math(EXPR _stripped_file_length "${_luajit_file_length} - ${_luajit_source_dir_length} - 1") string(SUBSTRING ${file} ${_begin} ${_stripped_file_length} stripped_file) set(generated_file "${CMAKE_BINARY_DIR}/luacode_tmp/${stripped_file}_${luajit_target}_generated.c") add_custom_command( OUTPUT ${generated_file} MAIN_DEPENDENCY ${source_file} DEPENDS lua COMMAND lua ARGS "${LUA_DIR}/../luac.lua" ${source_file} ${generated_file} COMMENT "Building Lua ${source_file}: ${generated_file}" ) get_filename_component(basedir ${generated_file} PATH) file(MAKE_DIRECTORY ${basedir}) set(target_srcs ${target_srcs} ${generated_file}) set_source_files_properties( ${generated_file} properties generated true # to say that "it is OK that the obj-files do not exist before build time" ) ELSE() set(target_srcs ${target_srcs} ${file}) ENDIF(${file} MATCHES ".*\\.lua$") ENDFOREACH(file) ENDMACRO() MACRO(LUA_ADD_EXECUTABLE luajit_target) LUA_add_custom_commands(${luajit_target} ${ARGN}) add_executable(${luajit_target} ${target_srcs}) ENDMACRO(LUA_ADD_EXECUTABLE luajit_target) luv-1.9.1-0/deps/lua_one.c000066400000000000000000000034151274770366500152320ustar00rootroot00000000000000/* * one.c -- Lua core, libraries, and interpreter in a single file */ /* default is to build the full interpreter */ #ifndef MAKE_LIB #ifndef MAKE_LUAC #ifndef MAKE_LUA #define MAKE_LIB #endif #endif #endif /* choose suitable platform-specific features */ /* some of these may need extra libraries such as -ldl -lreadline -lncurses */ #if 0 #define LUA_USE_LINUX #define LUA_USE_MACOSX #define LUA_USE_POSIX #define LUA_ANSI #endif /* no need to change anything below this line ----------------------------- */ /* setup for luaconf.h */ #if HAVE_LPREFIX # include "lprefix.h" #endif #define LUA_CORE #define LUA_LIB #define ltable_c #define lvm_c #include "luaconf.h" /* do not export internal symbols */ #undef LUAI_FUNC #undef LUAI_DDEC #undef LUAI_DDEF #define LUAI_FUNC static #define LUAI_DDEC static #define LUAI_DDEF static /* core -- used by all */ #include "lapi.c" #include "lcode.c" #include "lctype.c" #include "ldebug.c" #include "ldo.c" #include "ldump.c" #include "lfunc.c" #include "lgc.c" #include "llex.c" #include "lmem.c" #include "lobject.c" #include "lopcodes.c" #include "lparser.c" #include "lstate.c" #include "lstring.c" #include "ltable.c" #include "ltm.c" #include "lundump.c" #include "lvm.c" #include "lzio.c" /* auxiliary library -- used by all */ #include "lauxlib.c" /* standard library -- not used by luac */ #ifndef MAKE_LUAC #include "lbaselib.c" #if LUA_VERSION_NUM == 502 # include "lbitlib.c" #endif #include "lcorolib.c" #include "ldblib.c" #include "liolib.c" #include "lmathlib.c" #include "loadlib.c" #include "loslib.c" #include "lstrlib.c" #include "ltablib.c" #if LUA_VERSION_NUM >= 503 # include "lutf8lib.c" #endif #include "linit.c" #endif /* lua */ #ifdef MAKE_LUA #include "lua.c" #endif /* luac */ #ifdef MAKE_LUAC #include "luac.c" #endif luv-1.9.1-0/deps/luac.lua000066400000000000000000000043501274770366500150720ustar00rootroot00000000000000--[[ Copyright 2014 The Luvit Authors. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. s ]] local src, gen = ... local chunk = assert(loadfile(src, nil, '@'..src)) local bytecode = string.dump(chunk) local function basename(name) local base = name if base:match "[/\\]" then base = name:match("^.*[/\\](.*)$") end base = base:gsub("^%.", "_") if base:match "%." then base = base:match("^(.*)%."):gsub("%.", "_") end return base end local function escapefn(name) return '"'.. name:gsub('\\', '\\\\') :gsub('\n', '\\n') :gsub('\r', '\\r') :gsub('"', '\\"')..'"' end local function write_chunk(s) local t = { "{\n " }; local cc = 7 for i = 1, #s do local c = string.byte(s, i, i) local ss = (" 0x%X"):format(c) if cc + #ss > 77 then t[#t+1] = "\n " t[#t+1] = ss cc = 7 + #ss if i ~= #s then t[#t+1] = "," cc = cc + 1 end else t[#t+1] = ss cc = cc + #ss if i ~= #s then t[#t+1] = "," cc = cc + 1 end end end t[#t+1] = "\n }" return (table.concat(t)) end local function W(...) io.write(...) return W end io.output(gen) W [[ /* generated source for Lua codes */ #ifndef LUA_LIB # define LUA_LIB #endif #include #include LUALIB_API int luaopen_]](basename(src))[[(lua_State *L) { size_t len = ]](#bytecode)[[; const char chunk[] = ]](write_chunk(bytecode))[[; if (luaL_loadbuffer(L, chunk, len, ]](escapefn(src))[[) != 0) lua_error(L); lua_insert(L, 1); lua_call(L, lua_gettop(L)-1, LUA_MULTRET); return lua_gettop(L); } ]] io.close() luv-1.9.1-0/deps/luajit/000077500000000000000000000000001274770366500147315ustar00rootroot00000000000000luv-1.9.1-0/deps/luajit.cmake000066400000000000000000000274541274770366500157470ustar00rootroot00000000000000# Added LUA_ADD_EXECUTABLE Ryan Phillips # This CMakeLists.txt has been first taken from LuaDist # Copyright (C) 2007-2011 LuaDist. # Created by Peter Drahoš # Redistribution and use of this file is allowed according to the terms of the MIT license. # Debugged and (now seriously) modified by Ronan Collobert, for Torch7 #project(LuaJIT C ASM) SET(LUAJIT_DIR ${CMAKE_CURRENT_LIST_DIR}/luajit) SET(CMAKE_REQUIRED_INCLUDES ${LUAJIT_DIR} ${LUAJIT_DIR}/src ${CMAKE_CURRENT_BINARY_DIR} ) OPTION(WITH_AMALG "Build eveything in one shot (needs memory)" ON) # Ugly warnings IF(MSVC) ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS) ENDIF() # Various includes INCLUDE(CheckLibraryExists) INCLUDE(CheckFunctionExists) INCLUDE(CheckCSourceCompiles) INCLUDE(CheckTypeSize) # LuaJIT specific option(LUAJIT_DISABLE_FFI "Disable FFI." OFF) option(LUAJIT_ENABLE_LUA52COMPAT "Enable Lua 5.2 compatibility." ON) option(LUAJIT_DISABLE_JIT "Disable JIT." OFF) option(LUAJIT_CPU_SSE2 "Use SSE2 instead of x87 instructions." ON) option(LUAJIT_CPU_NOCMOV "Disable NOCMOV." OFF) MARK_AS_ADVANCED(LUAJIT_DISABLE_FFI LUAJIT_ENABLE_LUA52COMPAT LUAJIT_DISABLE_JIT LUAJIT_CPU_SSE2 LUAJIT_CPU_NOCMOV) IF(LUAJIT_DISABLE_FFI) ADD_DEFINITIONS(-DLUAJIT_DISABLE_FFI) ENDIF() IF(LUAJIT_ENABLE_LUA52COMPAT) ADD_DEFINITIONS(-DLUAJIT_ENABLE_LUA52COMPAT) ENDIF() IF(LUAJIT_DISABLE_JIT) ADD_DEFINITIONS(-DLUAJIT_DISABLE_JIT) ENDIF() IF(LUAJIT_CPU_SSE2) ADD_DEFINITIONS(-DLUAJIT_CPU_SSE2) ENDIF() IF(LUAJIT_CPU_NOCMOV) ADD_DEFINITIONS(-DLUAJIT_CPU_NOCMOV) ENDIF() ###### CHECK_TYPE_SIZE("void*" SIZEOF_VOID_P) IF(SIZEOF_VOID_P EQUAL 8) ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE) ENDIF() if ( WIN32 AND NOT CYGWIN ) add_definitions ( -DLUAJIT_OS=LUAJIT_OS_WINDOWS) set ( LJVM_MODE coffasm ) elseif ( APPLE ) set ( CMAKE_EXE_LINKER_FLAGS "-pagezero_size 10000 -image_base 100000000 ${CMAKE_EXE_LINKER_FLAGS}" ) set ( LJVM_MODE machasm ) else () set ( LJVM_MODE elfasm ) endif () IF(NOT WIN32) FIND_LIBRARY(DL_LIBRARY "dl") IF(DL_LIBRARY) SET(CMAKE_REQUIRED_LIBRARIES ${DL_LIBRARY}) LIST(APPEND LIBS ${DL_LIBRARY}) ENDIF(DL_LIBRARY) CHECK_FUNCTION_EXISTS(dlopen LUA_USE_DLOPEN) IF(NOT LUA_USE_DLOPEN) MESSAGE(FATAL_ERROR "Cannot compile a useful lua. Function dlopen() seems not to be supported on your platform. Apparently you are not on a Windows platform as well. So lua has no way to deal with shared libraries!") ENDIF(NOT LUA_USE_DLOPEN) ENDIF(NOT WIN32) check_library_exists(m sin "" LUA_USE_LIBM) if ( LUA_USE_LIBM ) list ( APPEND LIBS m ) endif () ## SOURCES MACRO(LJ_TEST_ARCH stuff) CHECK_C_SOURCE_COMPILES(" #undef ${stuff} #include \"lj_arch.h\" #if ${stuff} int main() { return 0; } #else #error \"not defined\" #endif " ${stuff}) ENDMACRO() MACRO(LJ_TEST_ARCH_VALUE stuff value) CHECK_C_SOURCE_COMPILES(" #undef ${stuff} #include \"lj_arch.h\" #if ${stuff} == ${value} int main() { return 0; } #else #error \"not defined\" #endif " ${stuff}_${value}) ENDMACRO() FOREACH(arch X64 X86 ARM PPC PPCSPE MIPS) LJ_TEST_ARCH(LJ_TARGET_${arch}) if(LJ_TARGET_${arch}) STRING(TOLOWER ${arch} TARGET_LJARCH) MESSAGE(STATUS "LuaJIT Target: ${TARGET_LJARCH}") BREAK() ENDIF() ENDFOREACH() IF(NOT TARGET_LJARCH) MESSAGE(FATAL_ERROR "architecture not supported") ELSE() MESSAGE(STATUS "LuaJIT target ${TARGET_LJARCH}") ENDIF() FILE(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/jit) FILE(GLOB jit_files ${LUAJIT_DIR}/src/jit/*.lua) FILE(COPY ${jit_files} DESTINATION ${CMAKE_BINARY_DIR}/jit) SET(DASM_ARCH ${TARGET_LJARCH}) SET(DASM_FLAGS) SET(TARGET_ARCH) LIST(APPEND TARGET_ARCH "LUAJIT_TARGET=LUAJIT_ARCH_${TARGET_LJARCH}") LJ_TEST_ARCH_VALUE(LJ_ARCH_BITS 64) IF(LJ_ARCH_BITS_64) SET(DASM_FLAGS ${DASM_FLAGS} -D P64) ENDIF() LJ_TEST_ARCH_VALUE(LJ_HASJIT 1) IF(LJ_HASJIT_1) SET(DASM_FLAGS ${DASM_FLAGS} -D JIT) ENDIF() LJ_TEST_ARCH_VALUE(LJ_HASFFI 1) IF(LJ_HASFFI_1) SET(DASM_FLAGS ${DASM_FLAGS} -D FFI) ENDIF() LJ_TEST_ARCH_VALUE(LJ_DUALNUM 1) IF(LJ_DUALNUM_1) SET(DASM_FLAGS ${DASM_FLAGS} -D DUALNUM) ENDIF() LJ_TEST_ARCH_VALUE(LJ_ARCH_HASFPU 1) IF(LJ_ARCH_HASFPU_1) SET(DASM_FLAGS ${DASM_FLAGS} -D FPU) LIST(APPEND TARGET_ARCH "LJ_ARCH_HASFPU=1") ELSE() LIST(APPEND TARGET_ARCH "LJ_ARCH_HASFPU=0") ENDIF() LJ_TEST_ARCH_VALUE(LJ_ABI_SOFTFP 1) IF(NOT LJ_ABI_SOFTFP_1) SET(DASM_FLAGS ${DASM_FLAGS} -D HFABI) LIST(APPEND TARGET_ARCH "LJ_ABI_SOFTFP=0") ELSE() LIST(APPEND TARGET_ARCH "LJ_ABI_SOFTFP=1") ENDIF() IF(WIN32) SET(DASM_FLAGS ${DASM_FLAGS} -LN -D WIN) ENDIF() IF(TARGET_LJARCH STREQUAL "x86") LJ_TEST_ARCH_VALUE(__SSE2__ 1) IF(__SSE2__1) SET(DASM_FLAGS ${DASM_FLAGS} -D SSE) ENDIF() ENDIF() IF(TARGET_LJARCH STREQUAL "x64") SET(DASM_ARCH "x86") ENDIF() IF(TARGET_LJARCH STREQUAL "ppc") LJ_TEST_ARCH_VALUE(LJ_ARCH_SQRT 1) IF(NOT LJ_ARCH_SQRT_1) SET(DASM_FLAGS ${DASM_FLAGS} -D SQRT) ENDIF() LJ_TEST_ARCH_VALUE(LJ_ARCH_PPC64 1) IF(NOT LJ_ARCH_PPC64_1) SET(DASM_FLAGS ${DASM_FLAGS} -D GPR64) ENDIF() ENDIF() add_executable(minilua ${LUAJIT_DIR}/src/host/minilua.c) SET_TARGET_PROPERTIES(minilua PROPERTIES COMPILE_DEFINITIONS "${TARGET_ARCH}") CHECK_LIBRARY_EXISTS(m sin "" MINILUA_USE_LIBM) if(MINILUA_USE_LIBM) TARGET_LINK_LIBRARIES(minilua m) endif() add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/buildvm_arch.h COMMAND minilua ${LUAJIT_DIR}/dynasm/dynasm.lua ${DASM_FLAGS} -o ${CMAKE_CURRENT_BINARY_DIR}/buildvm_arch.h ${LUAJIT_DIR}/src/vm_${DASM_ARCH}.dasc DEPENDS ${LUAJIT_DIR}/dynasm/dynasm.lua minilua ) SET(SRC_LJLIB ${LUAJIT_DIR}/src/lib_base.c ${LUAJIT_DIR}/src/lib_math.c ${LUAJIT_DIR}/src/lib_bit.c ${LUAJIT_DIR}/src/lib_string.c ${LUAJIT_DIR}/src/lib_table.c ${LUAJIT_DIR}/src/lib_io.c ${LUAJIT_DIR}/src/lib_os.c ${LUAJIT_DIR}/src/lib_package.c ${LUAJIT_DIR}/src/lib_debug.c ${LUAJIT_DIR}/src/lib_jit.c ${LUAJIT_DIR}/src/lib_ffi.c) SET(SRC_LJCORE ${LUAJIT_DIR}/src/lj_gc.c ${LUAJIT_DIR}/src/lj_err.c ${LUAJIT_DIR}/src/lj_char.c ${LUAJIT_DIR}/src/lj_buf.c ${LUAJIT_DIR}/src/lj_profile.c ${LUAJIT_DIR}/src/lj_strfmt.c ${LUAJIT_DIR}/src/lj_strfmt_num.c ${LUAJIT_DIR}/src/lj_bc.c ${LUAJIT_DIR}/src/lj_obj.c ${LUAJIT_DIR}/src/lj_str.c ${LUAJIT_DIR}/src/lj_tab.c ${LUAJIT_DIR}/src/lj_func.c ${LUAJIT_DIR}/src/lj_udata.c ${LUAJIT_DIR}/src/lj_meta.c ${LUAJIT_DIR}/src/lj_debug.c ${LUAJIT_DIR}/src/lj_state.c ${LUAJIT_DIR}/src/lj_dispatch.c ${LUAJIT_DIR}/src/lj_vmevent.c ${LUAJIT_DIR}/src/lj_vmmath.c ${LUAJIT_DIR}/src/lj_strscan.c ${LUAJIT_DIR}/src/lj_api.c ${LUAJIT_DIR}/src/lj_lex.c ${LUAJIT_DIR}/src/lj_parse.c ${LUAJIT_DIR}/src/lj_bcread.c ${LUAJIT_DIR}/src/lj_bcwrite.c ${LUAJIT_DIR}/src/lj_load.c ${LUAJIT_DIR}/src/lj_ir.c ${LUAJIT_DIR}/src/lj_opt_mem.c ${LUAJIT_DIR}/src/lj_opt_fold.c ${LUAJIT_DIR}/src/lj_opt_narrow.c ${LUAJIT_DIR}/src/lj_opt_dce.c ${LUAJIT_DIR}/src/lj_opt_loop.c ${LUAJIT_DIR}/src/lj_opt_split.c ${LUAJIT_DIR}/src/lj_opt_sink.c ${LUAJIT_DIR}/src/lj_mcode.c ${LUAJIT_DIR}/src/lj_snap.c ${LUAJIT_DIR}/src/lj_record.c ${LUAJIT_DIR}/src/lj_crecord.c ${LUAJIT_DIR}/src/lj_ffrecord.c ${LUAJIT_DIR}/src/lj_asm.c ${LUAJIT_DIR}/src/lj_trace.c ${LUAJIT_DIR}/src/lj_gdbjit.c ${LUAJIT_DIR}/src/lj_ctype.c ${LUAJIT_DIR}/src/lj_cdata.c ${LUAJIT_DIR}/src/lj_cconv.c ${LUAJIT_DIR}/src/lj_ccall.c ${LUAJIT_DIR}/src/lj_ccallback.c ${LUAJIT_DIR}/src/lj_carith.c ${LUAJIT_DIR}/src/lj_clib.c ${LUAJIT_DIR}/src/lj_cparse.c ${LUAJIT_DIR}/src/lj_lib.c ${LUAJIT_DIR}/src/lj_alloc.c ${LUAJIT_DIR}/src/lj_vmmath.c ${LUAJIT_DIR}/src/lib_aux.c ${LUAJIT_DIR}/src/lib_init.c ${SRC_LJLIB}) SET(SRC_BUILDVM ${LUAJIT_DIR}/src/host/buildvm.c ${LUAJIT_DIR}/src/host/buildvm_asm.c ${LUAJIT_DIR}/src/host/buildvm_peobj.c ${LUAJIT_DIR}/src/host/buildvm_lib.c ${LUAJIT_DIR}/src/host/buildvm_fold.c ${CMAKE_CURRENT_BINARY_DIR}/buildvm_arch.h) ## GENERATE ADD_EXECUTABLE(buildvm ${SRC_BUILDVM}) SET_TARGET_PROPERTIES(buildvm PROPERTIES COMPILE_DEFINITIONS "${TARGET_ARCH}") macro(add_buildvm_target _target _mode) add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_target} COMMAND buildvm ARGS -m ${_mode} -o ${CMAKE_CURRENT_BINARY_DIR}/${_target} ${ARGN} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS buildvm ${ARGN} ) endmacro(add_buildvm_target) if (MSVC) add_buildvm_target ( lj_vm.obj peobj ) set (LJ_VM_SRC ${CMAKE_CURRENT_BINARY_DIR}/lj_vm.obj) else () add_buildvm_target ( lj_vm.S ${LJVM_MODE} ) set (LJ_VM_SRC ${CMAKE_CURRENT_BINARY_DIR}/lj_vm.S) endif () add_buildvm_target ( lj_ffdef.h ffdef ${SRC_LJLIB} ) add_buildvm_target ( lj_bcdef.h bcdef ${SRC_LJLIB} ) add_buildvm_target ( lj_folddef.h folddef ${LUAJIT_DIR}/src/lj_opt_fold.c ) add_buildvm_target ( lj_recdef.h recdef ${SRC_LJLIB} ) add_buildvm_target ( lj_libdef.h libdef ${SRC_LJLIB} ) add_buildvm_target ( vmdef.lua vmdef ${SRC_LJLIB} ) SET(DEPS ${LJ_VM_SRC} ${CMAKE_CURRENT_BINARY_DIR}/lj_ffdef.h ${CMAKE_CURRENT_BINARY_DIR}/lj_bcdef.h ${CMAKE_CURRENT_BINARY_DIR}/lj_libdef.h ${CMAKE_CURRENT_BINARY_DIR}/lj_recdef.h ${CMAKE_CURRENT_BINARY_DIR}/lj_folddef.h ${CMAKE_CURRENT_BINARY_DIR}/vmdef.lua ) ## COMPILE include_directories( ${LUAJIT_DIR}/dynasm ${LUAJIT_DIR}/src ${CMAKE_CURRENT_BINARY_DIR} ) IF(WITH_SHARED_LUA) IF(WITH_AMALG) add_library(luajit-5.1 SHARED ${LUAJIT_DIR}/src/ljamalg.c ${DEPS} ) ELSE() add_library(luajit-5.1 SHARED ${SRC_LJCORE} ${DEPS} ) ENDIF() SET_TARGET_PROPERTIES(luajit-5.1 PROPERTIES OUTPUT_NAME "lua51") ELSE() IF(WITH_AMALG) add_library(luajit-5.1 STATIC ${LUAJIT_DIR}/src/ljamalg.c ${DEPS} ) ELSE() add_library(luajit-5.1 STATIC ${SRC_LJCORE} ${DEPS} ) ENDIF() SET_TARGET_PROPERTIES(luajit-5.1 PROPERTIES PREFIX "lib" IMPORT_PREFIX "lib" OUTPUT_NAME "luajit") ENDIF() target_link_libraries (luajit-5.1 ${LIBS} ) IF(WIN32) add_executable(luajit ${LUAJIT_DIR}/src/luajit.c) target_link_libraries(luajit luajit-5.1) ELSE() IF(WITH_AMALG) add_executable(luajit ${LUAJIT_DIR}/src/luajit.c ${LUAJIT_DIR}/src/ljamalg.c ${DEPS}) ELSE() add_executable(luajit ${LUAJIT_DIR}/src/luajit.c ${SRC_LJCORE} ${DEPS}) ENDIF() target_link_libraries(luajit ${LIBS}) SET_TARGET_PROPERTIES(luajit PROPERTIES ENABLE_EXPORTS ON) ENDIF() MACRO(LUAJIT_add_custom_commands luajit_target) SET(target_srcs "") FOREACH(file ${ARGN}) IF(${file} MATCHES ".*\\.lua$") set(file "${CMAKE_CURRENT_SOURCE_DIR}/${file}") set(source_file ${file}) string(LENGTH ${CMAKE_SOURCE_DIR} _luajit_source_dir_length) string(LENGTH ${file} _luajit_file_length) math(EXPR _begin "${_luajit_source_dir_length} + 1") math(EXPR _stripped_file_length "${_luajit_file_length} - ${_luajit_source_dir_length} - 1") string(SUBSTRING ${file} ${_begin} ${_stripped_file_length} stripped_file) set(generated_file "${CMAKE_BINARY_DIR}/jitted_tmp/${stripped_file}_${luajit_target}_generated${CMAKE_C_OUTPUT_EXTENSION}") add_custom_command( OUTPUT ${generated_file} MAIN_DEPENDENCY ${source_file} DEPENDS luajit COMMAND luajit ARGS -bg ${source_file} ${generated_file} COMMENT "Building Luajitted ${source_file}: ${generated_file}" ) get_filename_component(basedir ${generated_file} PATH) file(MAKE_DIRECTORY ${basedir}) set(target_srcs ${target_srcs} ${generated_file}) set_source_files_properties( ${generated_file} properties external_object true # this is an object file generated true # to say that "it is OK that the obj-files do not exist before build time" ) ELSE() set(target_srcs ${target_srcs} ${file}) ENDIF(${file} MATCHES ".*\\.lua$") ENDFOREACH(file) ENDMACRO() MACRO(LUA_ADD_EXECUTABLE luajit_target) LUAJIT_add_custom_commands(${luajit_target} ${ARGN}) add_executable(${luajit_target} ${target_srcs}) ENDMACRO(LUA_ADD_EXECUTABLE luajit_target) luv-1.9.1-0/deps/uv.cmake000066400000000000000000000145001274770366500150750ustar00rootroot00000000000000## Modifications ## Copyright 2014 The Luvit Authors. All Rights Reserved. ## Original Copyright # Copyright (c) 2014 David Capello # # 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(CheckTypeSize) cmake_minimum_required(VERSION 2.8.9) set(LIBUVDIR ${CMAKE_CURRENT_LIST_DIR}/libuv) include_directories( ${LIBUVDIR}/src ${LIBUVDIR}/include ) set(SOURCES ${LIBUVDIR}/include/uv.h ${LIBUVDIR}/include/tree.h ${LIBUVDIR}/include/uv-errno.h ${LIBUVDIR}/include/uv-threadpool.h ${LIBUVDIR}/include/uv-version.h ${LIBUVDIR}/src/fs-poll.c ${LIBUVDIR}/src/heap-inl.h ${LIBUVDIR}/src/inet.c ${LIBUVDIR}/src/queue.h ${LIBUVDIR}/src/threadpool.c ${LIBUVDIR}/src/uv-common.c ${LIBUVDIR}/src/uv-common.h ${LIBUVDIR}/src/version.c ) if(WIN32) add_definitions( -D_WIN32_WINNT=0x0600 -D_CRT_SECURE_NO_WARNINGS -D_GNU_SOURCE ) set(SOURCES ${SOURCES} ${LIBUVDIR}/include/uv-win.h ${LIBUVDIR}/src/win/async.c ${LIBUVDIR}/src/win/atomicops-inl.h ${LIBUVDIR}/src/win/core.c ${LIBUVDIR}/src/win/dl.c ${LIBUVDIR}/src/win/error.c ${LIBUVDIR}/src/win/fs.c ${LIBUVDIR}/src/win/fs-event.c ${LIBUVDIR}/src/win/getaddrinfo.c ${LIBUVDIR}/src/win/getnameinfo.c ${LIBUVDIR}/src/win/handle.c ${LIBUVDIR}/src/win/handle-inl.h ${LIBUVDIR}/src/win/internal.h ${LIBUVDIR}/src/win/loop-watcher.c ${LIBUVDIR}/src/win/pipe.c ${LIBUVDIR}/src/win/thread.c ${LIBUVDIR}/src/win/poll.c ${LIBUVDIR}/src/win/process.c ${LIBUVDIR}/src/win/process-stdio.c ${LIBUVDIR}/src/win/req.c ${LIBUVDIR}/src/win/req-inl.h ${LIBUVDIR}/src/win/signal.c ${LIBUVDIR}/src/win/snprintf.c ${LIBUVDIR}/src/win/stream.c ${LIBUVDIR}/src/win/stream-inl.h ${LIBUVDIR}/src/win/tcp.c ${LIBUVDIR}/src/win/tty.c ${LIBUVDIR}/src/win/timer.c ${LIBUVDIR}/src/win/udp.c ${LIBUVDIR}/src/win/util.c ${LIBUVDIR}/src/win/winapi.c ${LIBUVDIR}/src/win/winapi.h ${LIBUVDIR}/src/win/winsock.c ${LIBUVDIR}/src/win/winsock.h ) else() include_directories(${LIBUVDIR}/src/unix) set(SOURCES ${SOURCES} ${LIBUVDIR}/include/uv-unix.h ${LIBUVDIR}/include/uv-linux.h ${LIBUVDIR}/include/uv-sunos.h ${LIBUVDIR}/include/uv-darwin.h ${LIBUVDIR}/include/uv-bsd.h ${LIBUVDIR}/include/uv-aix.h ${LIBUVDIR}/src/unix/async.c ${LIBUVDIR}/src/unix/atomic-ops.h ${LIBUVDIR}/src/unix/core.c ${LIBUVDIR}/src/unix/dl.c ${LIBUVDIR}/src/unix/fs.c ${LIBUVDIR}/src/unix/getaddrinfo.c ${LIBUVDIR}/src/unix/getnameinfo.c ${LIBUVDIR}/src/unix/internal.h ${LIBUVDIR}/src/unix/loop.c ${LIBUVDIR}/src/unix/loop-watcher.c ${LIBUVDIR}/src/unix/pipe.c ${LIBUVDIR}/src/unix/poll.c ${LIBUVDIR}/src/unix/process.c ${LIBUVDIR}/src/unix/signal.c ${LIBUVDIR}/src/unix/spinlock.h ${LIBUVDIR}/src/unix/stream.c ${LIBUVDIR}/src/unix/tcp.c ${LIBUVDIR}/src/unix/thread.c ${LIBUVDIR}/src/unix/timer.c ${LIBUVDIR}/src/unix/tty.c ${LIBUVDIR}/src/unix/udp.c ) if(APPLE) set(SOURCES ${SOURCES} ${LIBUVDIR}/src/unix/pthread-barrier.c ) endif() endif() check_type_size("void*" SIZEOF_VOID_P) if(SIZEOF_VOID_P EQUAL 8) add_definitions(-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE) endif() ## Freebsd if("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD") set(SOURCES ${SOURCES} ${LIBUVDIR}/src/unix/kqueue.c ${LIBUVDIR}/src/unix/freebsd.c ) endif() ## OpenBSD if("${CMAKE_SYSTEM_NAME}" MATCHES "OpenBSD") set(SOURCES ${SOURCES} ${LIBUVDIR}/src/unix/kqueue.c ${LIBUVDIR}/src/unix/openbsd.c ) endif() ## Linux if("${CMAKE_SYSTEM_NAME}" MATCHES "Linux") add_definitions( -D_GNU_SOURCE ) set(SOURCES ${SOURCES} ${LIBUVDIR}/src/unix/proctitle.c ${LIBUVDIR}/src/unix/linux-core.c ${LIBUVDIR}/src/unix/linux-inotify.c ${LIBUVDIR}/src/unix/linux-syscalls.c ${LIBUVDIR}/src/unix/linux-syscalls.h ) endif() ## SunOS if("${CMAKE_SYSTEM_NAME}" MATCHES "SunOS") add_definitions( -D__EXTENSIONS__ -D_XOPEN_SOURCE=500 ) set(SOURCES ${SOURCES} ${LIBUVDIR}/src/unix/sunos.c ) endif() ## Darwin if(APPLE) add_definitions( -D=_DARWIN_USE_64_BIT_INODE ) set(SOURCES ${SOURCES} ${LIBUVDIR}/src/unix/proctitle.c ${LIBUVDIR}/src/unix/darwin.c ${LIBUVDIR}/src/unix/fsevents.c ${LIBUVDIR}/src/unix/darwin-proctitle.c ${LIBUVDIR}/src/unix/kqueue.c ) endif() add_library(uv STATIC ${SOURCES}) set_property(TARGET uv PROPERTY POSITION_INDEPENDENT_CODE ON) if("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD") target_link_libraries(uv pthread kvm ) endif() if("${CMAKE_SYSTEM_NAME}" MATCHES "OpenBSD") set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) target_link_libraries(uv Threads::Threads) endif() if("${CMAKE_SYSTEM_NAME}" MATCHES "Linux") target_link_libraries(uv pthread ) endif() if(WIN32) target_link_libraries(uv ws2_32.lib shell32.lib psapi.lib iphlpapi.lib advapi32.lib userenv.lib ) endif() if("${CMAKE_SYSTEM_NAME}" MATCHES "SunOS") target_link_libraries(uv kstat socket sendfile ) endif() if(APPLE) find_library(FOUNDATION_LIBRARY Foundation) find_library(CORESERVICES_LIBRARY CoreServices) find_library(APPLICATION_SERVICES_LIBRARY ApplicationServices) target_link_libraries(uv ${FOUNDATION_LIBRARY} ${CORESERVICES_LIBRARY} ${APPLICATION_SERVICES_LIBRARY} ) endif() luv-1.9.1-0/docs.md000066400000000000000000001174361274770366500137740ustar00rootroot00000000000000# LibUV in Lua The [luv][] project provides access to the multi-platform support library [libuv][] to lua code. It was primariliy developed for the [luvit][] project as the `uv` builtin module, but can be used in other lua environments. ### TCP Echo Server Example Here is a small example showing a TCP echo server: ```lua local uv = require('uv') local server = uv.new_tcp() server:bind("127.0.0.1", 1337) server:listen(128, function (err) assert(not err, err) local client = uv.new_tcp() server:accept(client) client:read_start(function (err, chunk) assert(not err, err) if chunk then client:write(chunk) else client:shutdown() client:close() end end) end) print("TCP server listening at 127.0.0.1 port 1337") uv.run() ``` ### Methods vs Functions As a quick note, [libuv][] is a C library and as such, there are no such things as methods. The [luv][] bindings allow calling the libuv functions as either functions or methods. For example, calling `server:bind(host, port)` is equivalent to calling `uv.tcp_bind(server, host, port)`. All wrapped uv types in lua have method shortcuts where is makes sense. Some are even renamed shorter like the `tcp_` prefix that removed in method form. Under the hood it's the exact same C function. ## Table Of Contents The rest of the docs are organized by libuv type. There is some hierarchy as most types are considered handles and some are considered streams. - [`uv_loop_t`][] — Event loop - [`uv_handle_t`][] — Base handle - [`uv_timer_t`][] — Timer handle - [`uv_prepare_t`][] — Prepare handle - [`uv_check_t`][] — Check handle - [`uv_idle_t`][] — Idle handle - [`uv_async_t`][] — Async handle - [`uv_poll_t`][] — Poll handle - [`uv_signal_t`][] — Signal handle - [`uv_process_t`][] — Process handle - [`uv_stream_t`][] — Stream handle - [`uv_tcp_t`][] — TCP handle - [`uv_pipe_t`][] — Pipe handle - [`uv_tty_t`][] — TTY handle - [`uv_udp_t`][] — UDP handle - [`uv_fs_event_t`][] — FS Event handle - [`uv_fs_poll_t`][] — FS Poll handle - [Filesystem operations][] - [DNS utility functions][] - [Miscellaneous utilities][] ## `uv_loop_t` — Event loop [`uv_loop_t`]: #uv_loop_t--event-loop The event loop is the central part of libuv’s functionality. It takes care of polling for i/o and scheduling callbacks to be run based on different sources of events. In [luv][], there is an implicit uv loop for every lua state that loads the library. You can use this library in an multithreaded environment as long as each thread has it's own lua state with corresponsding own uv loop. ### `uv.loop_close()` Closes all internal loop resources. This function must only be called once the loop has finished its execution or it will raise a UV_EBUSY error. ### `uv.run([mode])` > optional `mode` defaults to `"default"` This function runs the event loop. It will act differently depending on the specified mode: - `"default"`: Runs the event loop until there are no more active and referenced handles or requests. Always returns `false`. - `"once"`: Poll for i/o once. Note that this function blocks if there are no pending callbacks. Returns `false` when done (no active handles or requests left), or `true` if more callbacks are expected (meaning you should run the event loop again sometime in the future). - `"nowait"`: Poll for i/o once but don’t block if there are no pending callbacks. Returns `false` if done (no active handles or requests left), or `true` if more callbacks are expected (meaning you should run the event loop again sometime in the future). Luvit will implicitly call `uv.run()` after loading user code, but if you use the `luv` bindings directly, you need to call this after registering your initial set of event callbacks to start the event loop. ### `uv.loop_alive()` Returns true if there are active handles or request in the loop. ### `uv.stop()` Stop the event loop, causing `uv_run()` to end as soon as possible. This will happen not sooner than the next loop iteration. If this function was called before blocking for i/o, the loop won’t block for i/o on this iteration. ### `uv.backend_fd()` Get backend file descriptor. Only kqueue, epoll and event ports are supported. This can be used in conjunction with `uv_run("nowait")` to poll in one thread and run the event loop’s callbacks in another. **Note**: Embedding a kqueue fd in another kqueue pollset doesn’t work on all platforms. It’s not an error to add the fd but it never generates events. ### `uv.backend_timeout()` Get the poll timeout. The return value is in milliseconds, or -1 for no timeout. ### `uv.now()` Return the current timestamp in milliseconds. The timestamp is cached at the start of the event loop tick, see `uv.update_time()` for details and rationale. The timestamp increases monotonically from some arbitrary point in time. Don’t make assumptions about the starting point, you will only get disappointed. **Note**: Use `uv.hrtime()` if you need sub-millisecond granularity. ### `uv.update_time()` Update the event loop’s concept of “now”. Libuv caches the current time at the start of the event loop tick in order to reduce the number of time-related system calls. You won’t normally need to call this function unless you have callbacks that block the event loop for longer periods of time, where “longer” is somewhat subjective but probably on the order of a millisecond or more. ### `uv.walk(callback)` Walk the list of handles: `callback` will be executed with the handle. ```lua -- Example usage of uv.walk to close all handles that aren't already closing. uv.walk(function (handle) if not handle:is_closing() then handle:close() end end) ``` ## `uv_handle_t` — Base handle [`uv_handle_t`]: #uv_handle_t--base-handle `uv_handle_t` is the base type for all libuv handle types. Structures are aligned so that any libuv handle can be cast to `uv_handle_t`. All API functions defined here work with any handle type. ### `uv.is_active(handle)` > method form `handle:is_active()` Returns `true` if the handle is active, `false` if it’s inactive. What “active” means depends on the type of handle: - A [`uv_async_t`][] handle is always active and cannot be deactivated, except by closing it with uv_close(). - A [`uv_pipe_t`][], [`uv_tcp_t`][], [`uv_udp_t`][], etc. handlebasically any handle that deals with i/ois active when it is doing something that involves i/o, like reading, writing, connecting, accepting new connections, etc. - A [`uv_check_t`][], [`uv_idle_t`][], [`uv_timer_t`][], etc. handle is active when it has been started with a call to `uv.check_start()`, `uv.idle_start()`, etc. Rule of thumb: if a handle of type `uv_foo_t` has a `uv.foo_start()` function, then it’s active from the moment that function is called. Likewise, `uv.foo_stop()` deactivates the handle again. ### `uv.is_closing(handle)` > method form `handle:is_closing()` Returns `true` if the handle is closing or closed, `false` otherwise. **Note**: This function should only be used between the initialization of the handle and the arrival of the close callback. ### `uv.close(handle, callback)` > method form `handle:close(callback)` Request handle to be closed. `callback` will be called asynchronously after this call. This MUST be called on each handle before memory is released. Handles that wrap file descriptors are closed immediately but `callback` will still be deferred to the next iteration of the event loop. It gives you a chance to free up any resources associated with the handle. In-progress requests, like `uv_connect_t` or `uv_write_t`, are cancelled and have their callbacks called asynchronously with `status=UV_ECANCELED`. ### `uv.ref(handle)` > method form `handle:ref()` Reference the given handle. References are idempotent, that is, if a handle is already referenced calling this function again will have no effect. See [Reference counting][]. ### `uv.unref(handle)` > method form `handle:unref()` Un-reference the given handle. References are idempotent, that is, if a handle is not referenced calling this function again will have no effect. See [Reference counting][]. ### `uv.has_ref(handle)` > method form `handle:has_ref()` Returns `true` if the handle referenced, `false` otherwise. See [Reference counting][]. ### `uv.send_buffer_size(handle, [size]) -> size` > method form `handle:send_buffer_size(size)` Gets or sets the size of the send buffer that the operating system uses for the socket. If `size` is omitted, it will return the current send buffer size, otherwise it will use `size` to set the new send buffer size. This function works for TCP, pipe and UDP handles on Unix and for TCP and UDP handles on Windows. **Note**: Linux will set double the size and return double the size of the original set value. ### `uv.recv_buffer_size(handle, [size])` > method form `handle:recv_buffer_size(size)` Gets or sets the size of the receive buffer that the operating system uses for the socket. If `size` is omitted, it will return the current receive buffer size, otherwise it will use `size` to set the new receive buffer size. This function works for TCP, pipe and UDP handles on Unix and for TCP and UDP handles on Windows. **Note**: Linux will set double the size and return double the size of the original set value. ### `uv.fileno(handle)` > method form `handle:fileno()` Gets the platform dependent file descriptor equivalent. The following handles are supported: TCP, pipes, TTY, UDP and poll. Passing any other handle type will fail with UV_EINVAL. If a handle doesn’t have an attached file descriptor yet or the handle itself has been closed, this function will return UV_EBADF. **Warning**: Be very careful when using this function. libuv assumes it’s in control of the file descriptor so any change to it may lead to malfunction. ## Reference counting [reference counting]: #reference-counting The libuv event loop (if run in the default mode) will run until there are no active and referenced handles left. The user can force the loop to exit early by unreferencing handles which are active, for example by calling `uv.unref()` after calling `uv.timer_start()`. A handle can be referenced or unreferenced, the refcounting scheme doesn’t use a counter, so both operations are idempotent. All handles are referenced when active by default, see `uv.is_active()` for a more detailed explanation on what being active involves. ## `uv_timer_t` — Timer handle [`uv_timer_t`]: #uv_timer_t--timer-handle Timer handles are used to schedule callbacks to be called in the future. ### `uv.new_timer() -> timer` Creates and initializes a new `uv_timer_t`. Returns the lua userdata wrapping it. ```lua -- Creating a simple setTimeout wrapper local function setTimeout(timeout, callback) local timer = uv.new_timer() timer:start(timeout, 0, function () timer:stop() timer:close() callback() end) return timer end -- Creating a simple setInterval wrapper local function setInterval(interval, callback) local timer = uv.new_timer() timer:start(interval, interval, function () timer:stop() timer:close() callback() end) return timer end -- And clearInterval local function clearInterval(timer) timer:stop() timer:close() end ``` ### `uv.timer_start(timer, timeout, repeat, callback)` > method form `timer:start(timeout, repeat, callback)` Start the timer. `timeout` and `repeat` are in milliseconds. If `timeout` is zero, the callback fires on the next event loop iteration. If `repeat` is non-zero, the callback fires first after timeout milliseconds and then repeatedly after repeat milliseconds. ### `uv.timer_stop(timer)` > method form `timer:stop()` Stop the timer, the callback will not be called anymore. ### `uv.timer_again(timer)` > method form `timer:again()` Stop the timer, and if it is repeating restart it using the repeat value as the timeout. If the timer has never been started before it raises `EINVAL`. ### `uv.timer_set_repeat(timer, repeat)` > method form `timer:set_repeat(repeat)` Set the repeat value in milliseconds. **Note**: If the repeat value is set from a timer callback it does not immediately take effect. If the timer was non-repeating before, it will have been stopped. If it was repeating, then the old repeat value will have been used to schedule the next timeout. ### `uv.timer_get_repeat(timer) -> repeat` > method form `timer:get_repeat() -> repeat` Get the timer repeat value. ## `uv_prepare_t` — Prepare handle [`uv_prepare_t`]: #uv_prepare_t--prepare-handle Prepare handles will run the given callback once per loop iteration, right before polling for i/o. ```lua local prepare = uv.new_prepare() prepare:start(function() print("Before I/O polling") end) ``` ### `uv.new_prepare() -> prepare` Creates and initializes a new `uv_prepare_t`. Returns the lua userdata wrapping it. ### `uv.prepare_start(prepare, callback)` > method form `prepare:start(callback)` Start the handle with the given callback. ### `uv.prepare_stop(prepare)` > method form `prepare:stop()` Stop the handle, the callback will no longer be called. ## `uv_check_t` — Check handle [`uv_check_t`]: #uv_check_t--check-handle Check handles will run the given callback once per loop iteration, right after polling for i/o. ```lua local check = uv.new_check() check:start(function() print("After I/O polling") end) ``` ### `uv.new_check() -> check` Creates and initializes a new `uv_check_t`. Returns the lua userdata wrapping it. ### `uv.check_start(check, callback)` > method form `check:start(callback)` Start the handle with the given callback. ### `uv.check_stop(check)` > method form `check:stop()` Stop the handle, the callback will no longer be called. ## `uv_idle_t` — Idle handle [`uv_idle_t`]: #uv_idle_t--idle-handle Idle handles will run the given callback once per loop iteration, right before the [`uv_prepare_t`][] handles. **Note**: The notable difference with prepare handles is that when there are active idle handles, the loop will perform a zero timeout poll instead of blocking for i/o. **Warning**: Despite the name, idle handles will get their callbacks called on every loop iteration, not when the loop is actually “idle”. ```lua local idle = uv.new_idle() idle:start(function() print("Before I/O polling, no blocking") end) ``` ### `uv.new_idle() -> idle` Creates and initializes a new `uv_idle_t`. Returns the lua userdata wrapping it. ### `uv.idle_start(idle, callback)` > method form `idle:start(callback)` Start the handle with the given callback. ### `uv.idle_stop(check)` > method form `idle:stop()` Stop the handle, the callback will no longer be called. ## `uv_async_t` — Async handle [`uv_async_t`]: #uv_async_t--async-handle Async handles allow the user to “wakeup” the event loop and get a callback called from another thread. ```lua local async async = uv.new_async(function() print("async operation ran") async:close() end) async:send() ``` ### `uv.new_async(callback) -> async` Creates and initializes a new `uv_async_t`. Returns the lua userdata wrapping it. A NULL callback is allowed. **Note**: Unlike other handle initialization functions, it immediately starts the handle. ### `uv.async_send(async)` > method form `async:send()` Wakeup the event loop and call the async handle’s callback. **Note**: It’s safe to call this function from any thread. The callback will be called on the loop thread. **Warning**: libuv will coalesce calls to `uv.async_send(async)`, that is, not every call to it will yield an execution of the callback, the only guarantee is that it will be called at least once. Thus, calling this function may not wakeup the event loop if it was already called previously within a short period of time. ## `uv_poll_t` — Poll handle [`uv_poll_t`]: #uv_poll_t--poll-handle Poll handles are used to watch file descriptors for readability and writability, similar to the purpose of [poll(2)](http://linux.die.net/man/2/poll). The purpose of poll handles is to enable integrating external libraries that rely on the event loop to signal it about the socket status changes, like c-ares or libssh2. Using `uv_poll_t` for any other purpose is not recommended; `uv_tcp_t`, `uv_udp_t`, etc. provide an implementation that is faster and more scalable than what can be achieved with `uv_poll_t`, especially on Windows. It is possible that poll handles occasionally signal that a file descriptor is readable or writable even when it isn’t. The user should therefore always be prepared to handle EAGAIN or equivalent when it attempts to read from or write to the fd. It is not okay to have multiple active poll handles for the same socket, this can cause libuv to busyloop or otherwise malfunction. The user should not close a file descriptor while it is being polled by an active poll handle. This can cause the handle to report an error, but it might also start polling another socket. However the fd can be safely closed immediately after a call to `uv.poll_stop()` or `uv.close()`. **Note** On windows only sockets can be polled with poll handles. On Unix any file descriptor that would be accepted by poll(2) can be used. ### `uv.new_poll(fd) -> poll` Initialize the handle using a file descriptor. The file descriptor is set to non-blocking mode. ### `uv.new_socket_poll(fd) -> poll` Initialize the handle using a socket descriptor. On Unix this is identical to `uv.poll_init()`. On windows it takes a SOCKET handle. The socket is set to non-blocking mode. ### `uv.poll_start(poll, events, callback)` > method form `poll:start()` Starts polling the file descriptor. `events` is `"r"`, `"w"`, or `"rw"` and translates to a bitmask made up of UV_READABLE and UV_WRITABLE. As soon as an event is detected the callback will be called with status set to 0, and the detected events set on the events field. The user should not close the socket while the handle is active. If the user does that anyway, the callback may be called reporting an error status, but this is not guaranteed. **Note** Calling `uv.poll_start()`` on a handle that is already active is fine. Doing so will update the events mask that is being watched for. ## `uv.poll_stop(poll)` > method form `poll:stop()` Stop polling the file descriptor, the callback will no longer be called. ## `uv_signal_t` — Signal handle [`uv_signal_t`]: #uv_signal_t--signal-handle Signal handles implement Unix style signal handling on a per-event loop bases. Reception of some signals is emulated on Windows: * SIGINT is normally delivered when the user presses CTRL+C. However, like on Unix, it is not generated when terminal raw mode is enabled. * SIGBREAK is delivered when the user pressed CTRL + BREAK. * SIGHUP is generated when the user closes the console window. On SIGHUP the program is given approximately 10 seconds to perform cleanup. After that Windows will unconditionally terminate it. * SIGWINCH is raised whenever libuv detects that the console has been resized. SIGWINCH is emulated by libuv when the program uses a uv_tty_t handle to write to the console. SIGWINCH may not always be delivered in a timely manner; libuv will only detect size changes when the cursor is being moved. When a readable [`uv_tty_t`][] handle is used in raw mode, resizing the console buffer will also trigger a SIGWINCH signal. Watchers for other signals can be successfully created, but these signals are never received. These signals are: SIGILL, SIGABRT, SIGFPE, SIGSEGV, SIGTERM and SIGKILL. Calls to raise() or abort() to programmatically raise a signal are not detected by libuv; these will not trigger a signal watcher. **Note**: On Linux SIGRT0 and SIGRT1 (signals 32 and 33) are used by the NPTL pthreads library to manage threads. Installing watchers for those signals will lead to unpredictable behavior and is strongly discouraged. Future versions of libuv may simply reject them. ```lua -- Create a new signal handler local sigint = uv.new_signal() -- Define a handler function uv.signal_start(sigint, "sigint", function(signal) print("got " .. signal .. ", shutting down") os.exit(1) end) ``` ### `uv.new_signal() -> signal` Creates and initializes a new `uv_signal_t`. Returns the lua userdata wrapping it. ### `uv.signal_start(signal, signum, callback)` > method form `signal:start(signum, callback)` Start the handle with the given callback, watching for the given signal. ### `uv.signal_stop(signal)` > method form `signal:stop()` Stop the handle, the callback will no longer be called. ## `uv_process_t` — Process handle [`uv_process_t`]: #uv_process_t--process-handle Process handles will spawn a new process and allow the user to control it and establish communication channels with it using streams. ### `uv.disable_stdio_inheritance()` Disables inheritance for file descriptors / handles that this process inherited from its parent. The effect is that child processes spawned by this process don’t accidentally inherit these handles. It is recommended to call this function as early in your program as possible, before the inherited file descriptors can be closed or duplicated. **Note** This function works on a best-effort basis: there is no guarantee that libuv can discover all file descriptors that were inherited. In general it does a better job on Windows than it does on Unix. ### `uv.spawn(file, options, onexit) -> process, pid` Initializes the process handle and starts the process. If the process is successfully spawned, this function will return the handle and pid of the child process. Possible reasons for failing to spawn would include (but not be limited to) the file to execute not existing, not having permissions to use the setuid or setgid specified, or not having enough memory to allocate for the new process. ```lua local stdout = uv.new_pipe(false) local stderr = uv.new_pipe(false) local stdin = uv.new_pipe(false) local handle, pid local function onexit(code, signal) p("exit", {code=code,signal=signal}) end local function onclose() p("close") end local function onread(err, chunk) assert(not err, err) if (chunk) then p("data", {data=chunk}) else p("end") end end local function onshutdown() uv.close(handle, onclose) end handle, pid = uv.spawn("cat", { stdio = {stdin, stdout, stderr} }, onexit) p{ handle=handle, pid=pid } uv.read_start(stdout, onread) uv.read_start(stderr, onread) uv.write(stdin, "Hello World") uv.shutdown(stdin, onshutdown) ``` - `options.args` - Command line arguments as a list of string. The first string should be the path to the program. On Windows this uses CreateProcess which concatenates the arguments into a string this can cause some strange errors. (See `options.verbatim` below for Windows.) - `options.stdio` - Set the file descriptors that will be made available to the child process. The convention is that the first entries are stdin, stdout, and stderr. (**Note** On Windows file descriptors after the third are available to the child process only if the child processes uses the MSVCRT runtime.) - `options.env` - Set environment variables for the new process. - `options.cwd` - Set current working directory for the subprocess. - `options.uid` - Set the child process' user id. - `options.gid` - Set the child process' group id. - `options.verbatim` - If true, do not wrap any arguments in quotes, or perform any other escaping, when converting the argument list into a command line string. This option is only meaningful on Windows systems. On Unix it is silently ignored. - `options.detached` - If true, spawn the child process in a detached state - this will make it a process group leader, and will effectively enable the child to keep running after the parent exits. Note that the child process will still keep the parent's event loop alive unless the parent process calls `uv.unref()` on the child's process handle. - `options.hide` - If true, hide the subprocess console window that would normally be created. This option is only meaningful on Windows systems. On Unix it is silently ignored. The `options.stdio` entries can take many shapes. - If they are numbers, then the child process inherits that same zero-indexed fd from the parent process. - If `uv_stream_h` handles are passed in, those are used as a read-write pipe or inherited stream depending if the stream has a valid fd. - Including `nil` placeholders means to ignore that fd in the child. When the child process exits, the `onexit` callback will be called with exit code and signal. ### `uv.process_kill(process, sigmun)` > method form `process:kill(sigmun)` Sends the specified signal to the given process handle. ### `uv.kill(pid, sigmun)` Sends the specified signal to the given PID. ## `uv_stream_t` — Stream handle [`uv_stream_t`]: #uv_stream_t--stream-handle Stream handles provide an abstraction of a duplex communication channel. [`uv_stream_t`][] is an abstract type, libuv provides 3 stream implementations in the form of [`uv_tcp_t`][], [`uv_pipe_t`][] and [`uv_tty_t`][]. ### `uv.shutdown(stream, [callback]) -> req` > (method form `stream:shutdown([callback]) -> req`) Shutdown the outgoing (write) side of a duplex stream. It waits for pending write requests to complete. The callback is called after shutdown is complete. ### `uv.listen(stream, backlog, callback)` > (method form `stream:listen(backlog, callback)`) Start listening for incoming connections. `backlog` indicates the number of connections the kernel might queue, same as `listen(2)`. When a new incoming connection is received the callback is called. ### `uv.accept(stream, client_stream)` > (method form `stream:accept(client_stream)`) This call is used in conjunction with `uv.listen()` to accept incoming connections. Call this function after receiving a callback to accept the connection. When the connection callback is called it is guaranteed that this function will complete successfully the first time. If you attempt to use it more than once, it may fail. It is suggested to only call this function once per connection call. ```lua server:listen(128, function (err) local client = uv.new_tcp() server:accept(client) end) ``` ### `uv.read_start(stream, callback)` > (method form `stream:read_start(callback)`) Callback is of the form `(err, data)`. Read data from an incoming stream. The callback will be made several times until there is no more data to read or `uv.read_stop()` is called. When we’ve reached EOF, `data` will be `nil`. ```lua stream:read_start(function (err, chunk) if err then -- handle read error elseif chunk then -- handle data else -- handle disconnect end end) ``` ### `uv.read_stop(stream)` > (method form `stream:read_stop()`) Stop reading data from the stream. The read callback will no longer be called. ### `uv.write(stream, data, [callback])` > (method form `stream:write(data, [callback])`) Write data to stream. `data` can either be a lua string or a table of strings. If a table is passed in, the C backend will use writev to send all strings in a single system call. The optional `callback` is for knowing when the write is complete. ### `uv.write2(stream, data, send_handle, callback)` > (method form `stream:write2(data, send_handle, callback)`) Extended write function for sending handles over a pipe. The pipe must be initialized with ip option to `true`. **Note: `send_handle` must be a TCP socket or pipe, which is a server or a connection (listening or connected state). Bound sockets or pipes will be assumed to be servers. ### `uv.try_write(stream, data)` > (method form `stream:try_write(data)`) Same as `uv.write()`, but won’t queue a write request if it can’t be completed immediately. Will return number of bytes written (can be less than the supplied buffer size). ### `uv.is_readable(stream)` > (method form `stream:is_readable()`) Returns `true` if the stream is readable, `false` otherwise. ### `uv.is_writable(stream)` > (method form `stream:is_writable()`) Returns `true` if the stream is writable, `false` otherwise. ### `uv.stream_set_blocking(stream, blocking)` > (method form `stream:set_blocking(blocking)`) Enable or disable blocking mode for a stream. When blocking mode is enabled all writes complete synchronously. The interface remains unchanged otherwise, e.g. completion or failure of the operation will still be reported through a callback which is made asynchronously. **Warning**: Relying too much on this API is not recommended. It is likely to change significantly in the future. Currently this only works on Windows and only for uv_pipe_t handles. Also libuv currently makes no ordering guarantee when the blocking mode is changed after write requests have already been submitted. Therefore it is recommended to set the blocking mode immediately after opening or creating the stream. ## `uv_tcp_t` — TCP handle [`uv_tcp_t`]: #uv_tcp_t--tcp-handle TCP handles are used to represent both TCP streams and servers. `uv_tcp_t` is a ‘subclass’ of [`uv_stream_t`][](#uv_stream_t--stream-handle). ### `uv.new_tcp() -> tcp` Creates and initializes a new `uv_tcp_t`. Returns the lua userdata wrapping it. ### `uv.tcp_open(tcp, sock)` > (method form `tcp:open(sock)`) Open an existing file descriptor or SOCKET as a TCP handle. **Note: The user is responsible for setting the file descriptor in non-blocking mode. ### `uv.tcp_nodelay(tcp, enable)` > (method form `tcp:nodelay(enable)`) Enable / disable Nagle’s algorithm. ### `uv.tcp_keepalive(tcp, enable, [delay])` > (method form `tcp:keepalive(enable, [delay])`) Enable / disable TCP keep-alive. `delay` is the initial delay in seconds, ignored when enable is `false`. ### `uv.tcp_simultaneous_accepts(tcp, enable)` > (method form `tcp:simultaneous_accepts(enable)`) Enable / disable simultaneous asynchronous accept requests that are queued by the operating system when listening for new TCP connections. This setting is used to tune a TCP server for the desired performance. Having simultaneous accepts can significantly improve the rate of accepting connections (which is why it is enabled by default) but may lead to uneven load distribution in multi-process setups. ### `uv.tcp_bind(tcp, address, port)` > (method form `tcp:bind(address, port)`) Bind the handle to an address and port. `address` should be an IP address and not a domain name. When the port is already taken, you can expect to see an UV_EADDRINUSE error from either `uv.tcp_bind()`, `uv.listen()` or `uv.tcp_connect()`. That is, a successful call to this function does not guarantee that the call to `uv.listen()` or `uv.tcp_connect()` will succeed as well. Use a port of `0` to let the OS assign an ephemeral port. You can look it up later using `uv.tcp_getsockname()`. ### `uv.tcp_getsockname(tcp)` > (method form `tcp:getsockname()`) Get the current address to which the handle is bound. ### `uv.tcp_getpeername(tcp)` > (method form `tcp:getpeername()`) Get the address of the peer connected to the handle. ### `uv.tcp_connect(tcp, address, port, callback) -> req` > (method form `tcp:connect(host, port, callback) -> req`) ### `uv.tcp_write_queue_size(tcp) -> size` > (method form `tcp:write_queue_size() -> size`) Establish an IPv4 or IPv6 TCP connection. The callback is made when the connection has been established or when a connection error happened. ```lua local client = uv.new_tcp() client:connect("127.0.0.1", 8080, function (err) -- check error and carry on. end) ``` ## `uv_pipe_t` — Pipe handle [`uv_pipe_t`]: #uv_pipe_t--pipe-handle Pipe handles provide an abstraction over local domain sockets on Unix and named pipes on Windows. ```lua local pipe = uv.new_pipe(false) pipe:bind('/tmp/sock.test') pipe:listen(128, function() local client = uv.new_pipe(false) pipe:accept(client) client:write("hello!\n") client:close() end) ``` ### `uv.new_pipe(ipc) -> pipe` Creates and initializes a new `uv_pipe_t`. Returns the lua userdata wrapping it. The `ipc` argument is a boolean to indicate if this pipe will be used for handle passing between processes. ### `uv.pipe_open(file) -> pipe` Open an existing file descriptor or [`uv_handle_t`][] as a pipe. **Note**: The file descriptor is set to non-blocking mode. ### `uv.pipe_bind(pipe, name)` > (method form `pipe:bind(name)`) Bind the pipe to a file path (Unix) or a name (Windows). **Note**: Paths on Unix get truncated to sizeof(sockaddr_un.sun_path) bytes, typically between 92 and 108 bytes. ### `uv.pipe_connect(pipe, name, callback)` > (method form `pipe:connect(name, callback)`) Connect to the Unix domain socket or the named pipe. **Note**: Paths on Unix get truncated to sizeof(sockaddr_un.sun_path) bytes, typically between 92 and 108 bytes. ### `uv.pipe_getsockname(pipe)` > (method form `pipe:getsockname()`) Returns the name of the Unix domain socket or the named pipe. ### `uv.pipe_pending_instances(pipe, count)` > (method form `pipe:pending_instances(count)`) Set the number of pending pipe instance handles when the pipe server is waiting for connections. **Note**: This setting applies to Windows only. ### `uv.pipe_pending_count(pipe)` > (method form `pipe:pending_count()`) Returns the pending pipe count for the named pipe. ### `uv.pipe_pending_type(pipe)` > (method form `pipe:pending_type()`) Used to receive handles over IPC pipes. First - call [`uv.pipe_pending_count`][], if it’s > 0 then initialize a handle of the given type, returned by [`uv.pipe_pending_type`][] and call [`uv.accept(pipe, handle)`][]. ## `uv_tty_t` — TTY handle [`uv_tty_t`]: #uv_tty_t--tty-handle TTY handles represent a stream for the console. ```lua -- Simple echo program local stdin = uv.new_tty(0, true) local stdout = uv.new_tty(1, false) stdin:read_start(function (err, data) assert(not err, err) if data then stdout:write(data) else stdin:close() stdout:close() end end) ``` ### uv.new_tty(fd, readable) -> tty Initialize a new TTY stream with the given file descriptor. Usually the file descriptor will be: - 0 - stdin - 1 - stdout - 2 - stderr `readable, specifies if you plan on calling uv_read_start() with this stream. `stdin is readable, stdout is not. On Unix this function will try to open /dev/tty and use it if the passed file descriptor refers to a TTY. This lets libuv put the tty in non-blocking mode without affecting other processes that share the tty. Note: If opening `/dev/tty` fails, libuv falls back to blocking writes for non-readable TTY streams. ### uv.tty_set_mode(mode) > (method form `tty:set_mode(mode)`) Set the TTY using the specified terminal mode. Parameter `mode` is a C enum with the following values: - 0 - UV_TTY_MODE_NORMAL: Initial/normal terminal mode - 1 - UV_TTY_MODE_RAW: Raw input mode (On Windows, ENABLE_WINDOW_INPUT is also enabled) - 2 - UV_TTY_MODE_IO: Binary-safe I/O mode for IPC (Unix-only) ## uv.tty_reset_mode() To be called when the program exits. Resets TTY settings to default values for the next process to take over. This function is async signal-safe on Unix platforms but can fail with error code UV_EBUSY if you call it when execution is inside uv_tty_set_mode(). ## uv.tty_get_winsize() -> w, h > (method form `tty:get_winsize() -> w, h`) Gets the current Window size. ## `uv_udp_t` — UDP handle [`uv_udp_t`]: #uv_udp_t--udp-handle UDP handles encapsulate UDP communication for both clients and servers. ### uv.new_udp() -> udp Initialize a new UDP handle. The actual socket is created lazily. ### uv.udp_open(udp, fd) > (method form `udp:open(fd)`) Opens an existing file descriptor or Windows SOCKET as a UDP handle. Unix only: The only requirement of the sock argument is that it follows the datagram contract (works in unconnected mode, supports sendmsg()/recvmsg(), etc). In other words, other datagram-type sockets like raw sockets or netlink sockets can also be passed to this function. The file descriptor is set to non-blocking mode. Note: The passed file descriptor or SOCKET is not checked for its type, but it’s required that it represents a valid datagram socket. ### uv.udp_bind(udp, host, port) > (method form `udp:bind(host, port)`) Bind the UDP handle to an IP address and port. ### uv.udp_getsockname(udp) > (method form `udp:getsockname()`) Get the local IP and port of the UDP handle. ### uv.udp_set_membership(udp, multicast_addr, interface_addr, membership) > (method form `udp:set_membership(multicast_addr, interface_addr, membership)`) Set membership for a multicast address. `multicast_addr` is multicast address to set membership for. `interface_addr` is interface address. `membership` can be the string `"leave"` or `"join"`. ### uv.udp_set_multicast_loop(udp, on) > (method form `udp:set_multicast_loop(on)`) Set IP multicast loop flag. Makes multicast packets loop back to local sockets. `on` is a boolean. ### uv.udp_set_multicast_ttl(udp, tty) > (method form `udp:set_multicast_ttl(tty)`) Set the multicast ttl. `ttl` is an integer 1 through 255. ### uv.udp_set_multicast_interface(udp, interface_addr) > (method form `udp:set_multicast_interface(interface_addr)`) Set the multicast interface to send or receive data on. ### uv.udp_set_broadcast(udp, on) Set broadcast on or off. > (method form `udp:set_broadcast(, on)`) ### uv.udp_set_ttl(udp, ttl) > (method form `udp:set_ttl(ttl)`) Set the time to live. `ttl` is an integer 1 through 255. ### uv.udp_send(udp, data, host, port, callback) > (method form `udp:send(data, host, port, callback)`) Send data over the UDP socket. If the socket has not previously been bound with `uv_udp_bind()` it will be bound to `0.0.0.0` (the “all interfaces” IPv4 address) and a random port number. ### uv.udp_try_send(udp, data, host, port) > (method form `udp:try_send(data, host, port)`) Same as `uv_udp_send()`, but won’t queue a send request if it can’t be completed immediately. ### uv.udp_recv_start(udp, callback) > (method form `udp:recv_start(callback)`) Prepare for receiving data. If the socket has not previously been bound with `uv_udp_bind()` it is bound to `0.0.0.0` (the “all interfaces” IPv4 address) and a random port number. ### uv.udp_recv_stop(udp) > (method form `udp:recv_stop()`) ## `uv_fs_event_t` — FS Event handle [`uv_fs_event_t`]: #uv_fs_event_t--fs-event-handle **TODO**: port docs from [docs.libuv.org](http://docs.libuv.org/en/v1.x/fs_event.html) using [functions](https://github.com/luvit/luv/blob/25278a3871962cab29763692fdc3b270a7e96fe9/src/luv.c#L174-L177) and [methods](https://github.com/luvit/luv/blob/25278a3871962cab29763692fdc3b270a7e96fe9/src/luv.c#L265-L270) from [fs_event.c](https://github.com/luvit/luv/blob/master/src/fs_event.c) ## `uv_fs_poll_t` — FS Poll handle [`uv_fs_poll_t`]: #uv_fs_poll_t--fs-poll-handle **TODO**: port docs from [docs.libuv.org](http://docs.libuv.org/en/v1.x/fs_poll.html) using [functions](https://github.com/luvit/luv/blob/25278a3871962cab29763692fdc3b270a7e96fe9/src/luv.c#L180-L183) and [methods](https://github.com/luvit/luv/blob/25278a3871962cab29763692fdc3b270a7e96fe9/src/luv.c#L272-L277) from [fs_poll.c](https://github.com/luvit/luv/blob/master/src/fs_poll.c) ## Filesystem operations [Filesystem operations]:#filesystem-operations **TODO**: port docs from [docs.libuv.org](http://docs.libuv.org/en/v1.x/fs.html) using [functions](https://github.com/luvit/luv/blob/25278a3871962cab29763692fdc3b270a7e96fe9/src/luv.c#L186-L213) from [fs.c](https://github.com/luvit/luv/blob/master/src/fs.c) ## DNS utility functions [DNS utility functions]: #dns-utility-functions **TODO**: port docs from [docs.libuv.org](http://docs.libuv.org/en/v1.x/dns.html) using [functions](https://github.com/luvit/luv/blob/25278a3871962cab29763692fdc3b270a7e96fe9/src/luv.c#L216-L217) from [dns.c](https://github.com/luvit/luv/blob/master/src/dns.c) ## Miscellaneous utilities [Miscellaneous utilities]: #miscellaneous-utilities **TODO**: port docs from [docs.libuv.org](http://docs.libuv.org/en/v1.x/misc.html) using [functions](https://github.com/luvit/luv/blob/25278a3871962cab29763692fdc3b270a7e96fe9/src/luv.c#L220-L235) from [misc.c](https://github.com/luvit/luv/blob/master/src/misc.c) [luv]: https://github.com/luvit/luv [luvit]: https://github.com/luvit/luvit [libuv]: https://github.com/libuv/libuv luv-1.9.1-0/examples/000077500000000000000000000000001274770366500143245ustar00rootroot00000000000000luv-1.9.1-0/examples/cqueues-main.lua000066400000000000000000000007541274770366500174310ustar00rootroot00000000000000--[[ Demonstrates using luv with a cqueues mainloop ]] local cqueues = require "cqueues" local uv = require "luv" local cq = cqueues.new() cq:wrap(function() while cqueues.poll({ pollfd = uv.backend_fd(); timeout = uv.backend_timeout() / 1000; events = "r"; }) do uv.run("nowait") end end) cq:wrap(function() while true do cqueues.sleep(1) print("HELLO FROM CQUEUES") end end) uv.new_timer():start(1000, 1000, function() print("HELLO FROM LUV") end) assert(cq:loop()) luv-1.9.1-0/examples/cqueues-slave.lua000066400000000000000000000026371274770366500176210ustar00rootroot00000000000000--[[ Demonstrates using cqueues with a luv mainloop Starts a simple sleep+print loop using each library's native form. They should print intertwined. ]] local cqueues = require "cqueues" local uv = require "luv" local cq = cqueues.new() do local timer = uv.new_timer() local function reset_timer() local timeout = cq:timeout() if timeout then -- libuv takes milliseconds as an integer, -- while cqueues gives timeouts as a floating point number -- use `math.ceil` as we'd rather wake up late than early timer:set_repeat(math.ceil(timeout * 1000)) timer:again() else -- stop timer for now; it may be restarted later. timer:stop() end end local function onready() -- Step the cqueues loop once (sleeping for max 0 seconds) assert(cq:step(0)) reset_timer() end -- Need to call `start` on libuv timer now -- to provide callback and so that `again` works timer:start(0, 0, onready) -- Ask libuv to watch the cqueue pollfd uv.new_poll(cq:pollfd()):start(cq:events(), onready) end -- Adds a new function to the scheduler `cq` -- The functions is an infinite loop that sleeps for 1 second and prints cq:wrap(function() while true do cqueues.sleep(1) print("HELLO FROM CQUEUES") end end) -- Start a luv timer that fires every 1 second uv.new_timer():start(1000, 1000, function() print("HELLO FROM LUV") end) -- Run luv mainloop uv.run() luv-1.9.1-0/examples/echo-server-client.lua000066400000000000000000000027541274770366500205350ustar00rootroot00000000000000local p = require('lib/utils').prettyPrint local uv = require('luv') local function create_server(host, port, on_connection) local server = uv.new_tcp() p(1, server) uv.tcp_bind(server, host, port) uv.listen(server, 128, function(err) assert(not err, err) local client = uv.new_tcp() uv.accept(server, client) on_connection(client) end) return server end local server = create_server("0.0.0.0", 0, function (client) p("new client", client, uv.tcp_getsockname(client), uv.tcp_getpeername(client)) uv.read_start(client, function (err, chunk) p("onread", {err=err,chunk=chunk}) -- Crash on errors assert(not err, err) if chunk then -- Echo anything heard uv.write(client, chunk) else -- When the stream ends, close the socket uv.close(client) end end) end) local address = uv.tcp_getsockname(server) p("server", server, address) local client = uv.new_tcp() uv.tcp_connect(client, "127.0.0.1", address.port, function (err) assert(not err, err) uv.read_start(client, function (err, chunk) p("received at client", {err=err,chunk=chunk}) assert(not err, err) if chunk then uv.shutdown(client) p("client done shutting down") else uv.close(client) uv.close(server) end end) p("writing from client") uv.write(client, "Hello") uv.write(client, "World") end) -- Start the main event loop uv.run() -- Close any stray handles when done uv.walk(uv.close) uv.run() uv.loop_close() luv-1.9.1-0/examples/killing-children.lua000066400000000000000000000006001274770366500202420ustar00rootroot00000000000000local p = require('lib/utils').prettyPrint local uv = require('luv') local child, pid child, pid = uv.spawn("sleep", { args = {"100"} }, function (code, signal) p("EXIT", {code=code,signal=signal}) uv.close(child) end) p{child=child, pid=pid} -- uv.kill(pid, "SIGTERM") uv.process_kill(child, "SIGTERM") repeat print("\ntick.") until uv.run('once') == 0 print("done") luv-1.9.1-0/examples/lots-o-dns.lua000066400000000000000000000014751274770366500170350ustar00rootroot00000000000000local p = require('lib/utils').prettyPrint local uv = require('luv') uv.getaddrinfo(nil, 80, nil, p) local domains = { "facebook.com", "google.com", "mail.google.com", "maps.google.com", "plus.google.com", "play.google.com", "apple.com", "hp.com", "yahoo.com", "mozilla.com", "developer.mozilla.com", "luvit.io", "creationix.com", "howtonode.org", "github.com", "gist.github.com" } local i = 1 local function next() uv.getaddrinfo(domains[i], nil, { v4mapped = true, all = true, addrconfig = true, canonname = true, numericserv = true, socktype = "STREAM" }, function (err, data) assert(not err, err) p(data) i = i + 1 if i <= #domains then next() end end) end next(); repeat print("\nTick..") until uv.run('once') == 0 print("done") luv-1.9.1-0/examples/repl.lua000066400000000000000000000033661274770366500160010ustar00rootroot00000000000000local uv = require('luv') local utils = require('lib/utils') if uv.guess_handle(0) ~= "tty" or uv.guess_handle(1) ~= "tty" then error "stdio must be a tty" end local stdin = uv.new_tty(0, true) local stdout = require('lib/utils').stdout local debug = require('debug') local c = utils.color local function gatherResults(success, ...) local n = select('#', ...) return success, { n = n, ... } end local function printResults(results) for i = 1, results.n do results[i] = utils.dump(results[i]) end print(table.concat(results, '\t')) end local buffer = '' local function evaluateLine(line) if line == "<3\n" then print("I " .. c("Bred") .. "♥" .. c() .. " you too!") return '>' end local chunk = buffer .. line local f, err = loadstring('return ' .. chunk, 'REPL') -- first we prefix return if not f then f, err = loadstring(chunk, 'REPL') -- try again without return end if f then buffer = '' local success, results = gatherResults(xpcall(f, debug.traceback)) if success then -- successful call if results.n > 0 then printResults(results) end else -- error print(results[1]) end else if err:match "''$" then -- Lua expects some more input; stow it away for next time buffer = chunk .. '\n' return '>>' else print(err) buffer = '' end end return '>' end local function displayPrompt(prompt) uv.write(stdout, prompt .. ' ') end local function onread(err, line) if err then error(err) end if line then local prompt = evaluateLine(line) displayPrompt(prompt) else uv.close(stdin) end end coroutine.wrap(function() displayPrompt '>' uv.read_start(stdin, onread) end)() uv.run() print("") luv-1.9.1-0/examples/talking-to-children.lua000066400000000000000000000014141274770366500206660ustar00rootroot00000000000000local p = require('lib/utils').prettyPrint local uv = require('luv') local stdout = uv.new_pipe(false) local stderr = uv.new_pipe( false) local stdin = uv.new_pipe(false) local handle, pid local function onexit(code, signal) p("exit", {code=code,signal=signal}) end local function onclose() p("close") end local function onread(err, chunk) assert(not err, err) if (chunk) then p("data", {data=chunk}) else p("end") end end local function onshutdown() uv.close(handle, onclose) end handle, pid = uv.spawn("cat", { stdio = {stdin, stdout, stderr} }, onexit) p{ handle=handle, pid=pid } uv.read_start(stdout, onread) uv.read_start(stderr, onread) uv.write(stdin, "Hello World") uv.shutdown(stdin, onshutdown) uv.run() uv.walk(uv.close) uv.run() luv-1.9.1-0/examples/tcp-cluster.lua000066400000000000000000000042761274770366500173050ustar00rootroot00000000000000 -- This function will be run in a child process local child_code = string.dump(function () local p = require('lib/utils').prettyPrint local uv = require('luv') -- The parent is going to pass us the server handle over a pipe -- This will be our local file descriptor at PIPE_FD local pipe = uv.new_pipe(true) local pipe_fd = tonumber(os.getenv("PIPE_FD")) assert(uv.pipe_open(pipe, pipe_fd)) -- Configure the server handle local server = uv.new_tcp() local function onconnection() local client = uv.new_tcp() uv.accept(server, client) p("New TCP", client, "on", server) p{client=client} uv.write(client, "BYE!\n"); uv.shutdown(client, function () uv.close(client) uv.close(server) end) end -- Read the server handle from the parent local function onread(err, data) p("onread", {err=err,data=data}) assert(not err, err) if uv.pipe_pending_count(pipe) > 0 then local pending_type = uv.pipe_pending_type(pipe) p("pending_type", pending_type) assert(pending_type == "tcp") assert(uv.accept(pipe, server)) assert(uv.listen(server, 128, onconnection)) p("Received server handle from parent process", server) elseif data then p("ondata", data) else p("onend", data) end end uv.read_start(pipe, onread) -- Start the event loop! uv.run() end) local p = require('lib/utils').prettyPrint local uv = require('luv') local exepath = assert(uv.exepath()) local cpu_count = # assert(uv.cpu_info()) local server = uv.new_tcp() assert(uv.tcp_bind(server, "::1", 1337)) print("Master process bound to TCP port 1337 on ::1") local function onexit(status, signal) p("Child exited", {status=status,signal=signal}) end local function spawnChild() local pipe = uv.new_pipe(true) local input = uv.new_pipe(false) local _, pid = assert(uv.spawn(exepath, { stdio = {input,1,2,pipe}, env= {"PIPE_FD=3"} }, onexit)) uv.write(input, child_code) uv.shutdown(input) p("Spawned child", pid, "and sending handle", server) assert(uv.write2(pipe, "123", server)) assert(uv.shutdown(pipe)) end -- Spawn a child process for each CPU core for _ = 1, cpu_count do spawnChild() end uv.run() luv-1.9.1-0/examples/timers.lua000066400000000000000000000023501274770366500163320ustar00rootroot00000000000000local p = require('lib/utils').prettyPrint local uv = require('luv') local function set_timeout(timeout, callback) local timer = uv.new_timer() local function ontimeout() p("ontimeout", timer) uv.timer_stop(timer) uv.close(timer) callback(timer) end uv.timer_start(timer, timeout, 0, ontimeout) return timer end local function clear_timeout(timer) uv.timer_stop(timer) uv.close(timer) end local function set_interval(interval, callback) local timer = uv.new_timer() local function ontimeout() p("interval", timer) callback(timer) end uv.timer_start(timer, interval, interval, ontimeout) return timer end local clear_interval = clear_timeout local i = set_interval(300, function() print("interval...") end) set_timeout(1000, function() clear_interval(i) end) local handle = uv.new_timer() local delay = 1024 local function ontimeout() p("tick", delay) delay = delay / 2 if delay >= 1 then uv.timer_set_repeat(handle, delay) uv.timer_again(handle) else uv.timer_stop(handle) uv.close(handle) p("done") end end uv.timer_start(handle, delay, 0, ontimeout) repeat print("\ntick.") until uv.run('once') == 0 print("done") uv.walk(uv.close) uv.run() uv.loop_close() luv-1.9.1-0/examples/uvbook/000077500000000000000000000000001274770366500156315ustar00rootroot00000000000000luv-1.9.1-0/examples/uvbook/helloworld.lua000066400000000000000000000001241274770366500205040ustar00rootroot00000000000000local uv = require('luv') print('Now quitting.') uv.run('default') uv.loop_close() luv-1.9.1-0/examples/uvbook/idle-basic.lua000066400000000000000000000003521274770366500203300ustar00rootroot00000000000000local uv = require('luv') local counter = 0 local idle = uv.new_idle() idle:start(function() counter = counter + 1 if counter >= 10e6 then idle:stop() end end) print("Idling...") uv.run('default') uv.loop_close()luv-1.9.1-0/examples/uvbook/onchange.lua000066400000000000000000000013171274770366500201200ustar00rootroot00000000000000local uv = require('luv') if #arg==0 then print(string.format("Usage: %s [file2 ...]",arg[0])); return end for i=1,#arg do local fse = uv.new_fs_event() assert(uv.fs_event_start(fse,arg[i],{ --"watch_entry"=true,"stat"=true, recursive=true },function (err,fname,status) if(err) then print("Error "..err) else print(string.format('Change detected in %s', uv.fs_event_getpath(fse))) for k,v in pairs(status) do print(k,v) end print('file changed:'..(fname and fname or '')) end end)) end uv.run('default') uv.loop_close() luv-1.9.1-0/examples/uvbook/queue-work.lua000066400000000000000000000006761274770366500204510ustar00rootroot00000000000000local uv = require('luv') local ctx = uv.new_work( function(n) --work,in threadpool local uv = require('luv') local t = uv.thread_self() uv.sleep(100) return n*n,n end, function(r,n) print(string.format('%d => %d',n,r)) end --after work, in loop thread ) uv.queue_work(ctx,2) uv.queue_work(ctx,4) uv.queue_work(ctx,6) uv.queue_work(ctx,8) uv.queue_work(ctx,10) uv.run('default') uv.loop_close() luv-1.9.1-0/examples/uvbook/tcp-echo-client.lua000066400000000000000000000006621274770366500213160ustar00rootroot00000000000000local uv = require('luv') local client = uv.new_tcp() uv.tcp_connect(client, "127.0.0.1", 1337, function (err) assert(not err, err) uv.read_start(client, function (err, chunk) assert(not err, err) if chunk then print(chunk) else uv.close(client) end end) uv.write(client, "Hello") uv.write(client, "World") end) print('CTRL-C to break') uv.run('default') uv.loop_close() luv-1.9.1-0/examples/uvbook/tcp-echo-server.lua000066400000000000000000000006421274770366500213440ustar00rootroot00000000000000local uv = require('luv') local server = uv.new_tcp() server:bind("127.0.0.1", 1337) server:listen(128, function (err) assert(not err, err) local client = uv.new_tcp() server:accept(client) client:read_start(function (err, chunk) assert(not err, err) if chunk then client:write(chunk) else client:shutdown() client:close() end end) end) uv.run('default') uv.loop_close() luv-1.9.1-0/examples/uvbook/thread-create.lua000066400000000000000000000017761274770366500210570ustar00rootroot00000000000000local uv = require('luv') local step = 10 local hare_id = uv.new_thread(function(step,...) local ffi = require'ffi' local uv = require('luv') local sleep if ffi.os=='Windows' then ffi.cdef "void Sleep(int ms);" sleep = ffi.C.Sleep else ffi.cdef "unsigned int usleep(unsigned int seconds);" sleep = ffi.C.usleep end while (step>0) do step = step - 1 uv.sleep(math.random(1000)) print("Hare ran another step") end print("Hare done running!") end, step,true,'abcd','false') local tortoise_id = uv.new_thread(function(step,...) local uv = require('luv') while (step>0) do step = step - 1 uv.sleep(math.random(100)) print("Tortoise ran another step") end print("Tortoise done running!") end,step,'abcd','false') print(hare_id==hare_id,uv.thread_equal(hare_id,hare_id)) print(tortoise_id==hare_id,uv.thread_equal(tortoise_id,hare_id)) uv.thread_join(hare_id) uv.thread_join(tortoise_id) luv-1.9.1-0/examples/uvbook/uvcat.lua000066400000000000000000000016221274770366500174570ustar00rootroot00000000000000local uv = require('luv') local fname = arg[1] and arg[1] or arg[0] uv.fs_open(fname, 'r', tonumber('644', 8), function(err,fd) if err then print("error opening file:"..err) else local stat = uv.fs_fstat(fd) local off = 0 local block = 10 local function on_read(err,chunk) if(err) then print("Read error: "..err); elseif #chunk==0 then uv.fs_close(fd) else off = block + off uv.fs_write(1,chunk,-1,function(err,chunk) if err then print("Write error: "..err) else uv.fs_read(fd, block, off, on_read) end end) end end uv.fs_read(fd, block, off, on_read) end end) uv.run('default') uv.loop_close() luv-1.9.1-0/examples/uvbook/uvtee.lua000066400000000000000000000014101274770366500174600ustar00rootroot00000000000000local uv = require('luv') if not arg[1] then print(string.format("please run %s filename",arg[0])) return end local stdin = uv.new_tty(0, true) local stdout = uv.new_tty(1, true) --local stdin_pipe = uv.new_pipe(false) --uv.pipe_open(stdin_pipe,0) local fname = arg[1] uv.fs_open(fname, 'w+', tonumber('644', 8), function(err,fd) if err then print("error opening file:"..err) else local fpipe = uv.new_pipe(false) uv.pipe_open(fpipe, fd) uv.read_start(stdin, function(err,chunk) if err then print('Read error: '..err) else uv.write(stdout,chunk) uv.write(fpipe,chunk) end end); end end) uv.run('default') uv.loop_close() luv-1.9.1-0/lib/000077500000000000000000000000001274770366500132545ustar00rootroot00000000000000luv-1.9.1-0/lib/tap.lua000066400000000000000000000071161274770366500145500ustar00rootroot00000000000000local uv = require('luv') local dump = require('lib/utils').dump local stdout = require('lib/utils').stdout local function protect(...) local n = select('#', ...) local arguments = {...} for i = 1, n do arguments[i] = tostring(arguments[i]) end local text = table.concat(arguments, "\t") text = " " .. string.gsub(text, "\n", "\n ") print(text) end local function pprotect(...) local n = select('#', ...) local arguments = { ... } for i = 1, n do arguments[i] = dump(arguments[i]) end protect(table.concat(arguments, "\t")) end local tests = {}; local function run() local passed = 0 if #tests < 1 then error("No tests specified!") end print("1.." .. #tests) for i = 1, #tests do local test = tests[i] local cwd = uv.cwd() local pass, err = xpcall(function () local expected = 0 local function expect(fn, count) expected = expected + (count or 1) return function (...) expected = expected - 1 local ret = fn(...) collectgarbage() return ret end end test.fn(protect, pprotect, expect, uv) collectgarbage() uv.run() collectgarbage() if expected > 0 then error("Missing " .. expected .. " expected call" .. (expected == 1 and "" or "s")) elseif expected < 0 then error("Found " .. -expected .. " unexpected call" .. (expected == -1 and "" or "s")) end collectgarbage() local unclosed = 0 uv.walk(function (handle) if handle == stdout then return end unclosed = unclosed + 1 print("UNCLOSED", handle) end) if unclosed > 0 then error(unclosed .. " unclosed handle" .. (unclosed == 1 and "" or "s")) end if uv.cwd() ~= cwd then error("Test moved cwd from " .. cwd .. " to " .. uv.cwd()) end collectgarbage() end, debug.traceback) -- Flush out any more opened handles uv.stop() uv.walk(function (handle) if handle == stdout then return end if not uv.is_closing(handle) then uv.close(handle) end end) uv.run() uv.chdir(cwd) if pass then print("ok " .. i .. " " .. test.name) passed = passed + 1 else protect(err) print("not ok " .. i .. " " .. test.name) end end local failed = #tests - passed if failed == 0 then print("# All tests passed") else print("#" .. failed .. " failed test" .. (failed == 1 and "" or "s")) end -- Close all then handles, including stdout uv.walk(uv.close) uv.run() os.exit(-failed) end local single = true local prefix local function tap(suite) if type(suite) == "function" then -- Pass in suite directly for single mode suite(function (name, fn) if prefix then name = prefix .. ' - ' .. name end tests[#tests + 1] = { name = name, fn = fn } end) prefix = nil elseif type(suite) == "string" then prefix = suite single = false else -- Or pass in false to collect several runs of tests -- And then pass in true in a later call to flush tests queue. single = suite end if single then run() end end --[[ -- Sample Usage local passed, failed, total = tap(function (test) test("add 1 to 2", function(print) print("Adding 1 to 2") assert(1 + 2 == 3) end) test("close handle", function (print, p, expect, uv) local handle = uv.new_timer() uv.close(handle, expect(function (self) assert(self == handle) end)) end) test("simulate failure", function () error("Oopsie!") end) end) ]] return tap luv-1.9.1-0/lib/utils.lua000066400000000000000000000076721274770366500151330ustar00rootroot00000000000000 local uv = require('luv') local utils = {} local usecolors if uv.guess_handle(1) == "tty" then utils.stdout = uv.new_tty(1, false) usecolors = true else utils.stdout = uv.new_pipe(false) uv.pipe_open(utils.stdout, 1) usecolors = false end local colors = { black = "0;30", red = "0;31", green = "0;32", yellow = "0;33", blue = "0;34", magenta = "0;35", cyan = "0;36", white = "0;37", B = "1;", Bblack = "1;30", Bred = "1;31", Bgreen = "1;32", Byellow = "1;33", Bblue = "1;34", Bmagenta = "1;35", Bcyan = "1;36", Bwhite = "1;37" } function utils.color(color_name) if usecolors then return "\27[" .. (colors[color_name] or "0") .. "m" else return "" end end function utils.colorize(color_name, string, reset_name) return utils.color(color_name) .. tostring(string) .. utils.color(reset_name) end local backslash, null, newline, carriage, tab, quote, quote2, obracket, cbracket function utils.loadColors(n) if n ~= nil then usecolors = n end backslash = utils.colorize("Bgreen", "\\\\", "green") null = utils.colorize("Bgreen", "\\0", "green") newline = utils.colorize("Bgreen", "\\n", "green") carriage = utils.colorize("Bgreen", "\\r", "green") tab = utils.colorize("Bgreen", "\\t", "green") quote = utils.colorize("Bgreen", '"', "green") quote2 = utils.colorize("Bgreen", '"') obracket = utils.colorize("B", '[') cbracket = utils.colorize("B", ']') end utils.loadColors() function utils.dump(o, depth) local t = type(o) if t == 'string' then return quote .. o:gsub("\\", backslash):gsub("%z", null):gsub("\n", newline):gsub("\r", carriage):gsub("\t", tab) .. quote2 end if t == 'nil' then return utils.colorize("Bblack", "nil") end if t == 'boolean' then return utils.colorize("yellow", tostring(o)) end if t == 'number' then return utils.colorize("blue", tostring(o)) end if t == 'userdata' then return utils.colorize("magenta", tostring(o)) end if t == 'thread' then return utils.colorize("Bred", tostring(o)) end if t == 'function' then return utils.colorize("cyan", tostring(o)) end if t == 'cdata' then return utils.colorize("Bmagenta", tostring(o)) end if t == 'table' then if type(depth) == 'nil' then depth = 0 end if depth > 1 then return utils.colorize("yellow", tostring(o)) end local indent = (" "):rep(depth) -- Check to see if this is an array local is_array = true local i = 1 for k,v in pairs(o) do if not (k == i) then is_array = false end i = i + 1 end local first = true local lines = {} i = 1 local estimated = 0 for k,v in (is_array and ipairs or pairs)(o) do local s if is_array then s = "" else if type(k) == "string" and k:find("^[%a_][%a%d_]*$") then s = k .. ' = ' else s = '[' .. utils.dump(k, 100) .. '] = ' end end s = s .. utils.dump(v, depth + 1) lines[i] = s estimated = estimated + #s i = i + 1 end if estimated > 200 then return "{\n " .. indent .. table.concat(lines, ",\n " .. indent) .. "\n" .. indent .. "}" else return "{ " .. table.concat(lines, ", ") .. " }" end end -- This doesn't happen right? return tostring(o) end -- Print replacement that goes through libuv. This is useful on windows -- to use libuv's code to translate ansi escape codes to windows API calls. function print(...) local n = select('#', ...) local arguments = {...} for i = 1, n do arguments[i] = tostring(arguments[i]) end uv.write(utils.stdout, table.concat(arguments, "\t") .. "\n") end -- A nice global data dumper function utils.prettyPrint(...) local n = select('#', ...) local arguments = { ... } for i = 1, n do arguments[i] = utils.dump(arguments[i]) end print(table.concat(arguments, "\t")) end return utils luv-1.9.1-0/luv-1.9.1-0.rockspec000066400000000000000000000014121274770366500156460ustar00rootroot00000000000000package = "luv" version = "1.9.1-0" source = { url = 'https://github.com/luvit/luv/releases/download/'..version..'/luv-'..version..'.tar.gz' } description = { summary = "Bare libuv bindings for lua", detailed = [[ libuv bindings for luajit and lua 5.1/5.2/5.3. This library makes libuv available to lua scripts. It was made for the luvit project but should usable from nearly any lua project. ]], homepage = "https://github.com/luvit/luv", license = "Apache 2.0" } dependencies = { "lua >= 5.1" } build = { type = 'cmake', variables = { CMAKE_C_FLAGS="$(CFLAGS)", CMAKE_MODULE_LINKER_FLAGS="$(LIBFLAG)", LUA_LIBDIR="$(LUA_LIBDIR)", LUA_INCDIR="$(LUA_INCDIR)", LUA="$(LUA)", LIBDIR="$(LIBDIR)", LUADIR="$(LUADIR)", }, } luv-1.9.1-0/msvcbuild.bat000066400000000000000000000005131274770366500151650ustar00rootroot00000000000000@echo off set VS=12 if "%configuration%"=="2015" (set VS=14) if "%configuration%"=="2013" (set VS=12) if not defined platform set platform=x64 if "%platform%" EQU "x64" (set VS=%VS% Win64) cmake -H. -Bbuild -G"Visual Studio %VS%" cmake --build build --config Release copy build\Release\luv.dll . copy build\Release\luajit.exe . luv-1.9.1-0/rockspecs/000077500000000000000000000000001274770366500145025ustar00rootroot00000000000000luv-1.9.1-0/rockspecs/luv-1.9.1-0.rockspec000066400000000000000000000030211274770366500176400ustar00rootroot00000000000000-- Alternate rockspec that uses luarocks builtin builder package = "luv" version = "1.9.1-0" source = { url = 'https://github.com/luvit/luv/releases/download/'..version..'/luv-'..version..'.tar.gz' } description = { summary = "Bare libuv bindings for lua", detailed = [[ libuv bindings for luajit and lua 5.1/5.2/5.3. This library makes libuv available to lua scripts. It was made for the luvit project but should usable from nearly any lua project. ]], homepage = "https://github.com/luvit/luv", license = "Apache 2.0" } dependencies = { "lua >= 5.1" } external_dependencies = { LIBUV = { header = 'uv.h' } } build = { type = 'builtin', -- default (platform-agnostic) configuration modules = { ['luv'] = { sources = {'src/luv.c'}, libraries = {'uv'}, incdirs = {"$(LIBUV_INCDIR)"}, libdirs = {"$(LIBUV_LIBDIR)"} } }; -- per-platform overrides platforms = { linux = { modules = { ['luv'] = { libraries = { nil; 'pthread'; 'rt'; 'dl'; }; }; }; }; freebsd = { modules = { ['luv'] = { libraries = { nil; 'pthread'; 'kvm'; }; }; }; }; windows = { modules = { ['luv'] = { libraries = { nil; 'psapi'; 'iphlpapi'; 'userenv'; 'ws2_32'; 'advapi32'; }; }; }; }; } } luv-1.9.1-0/src/000077500000000000000000000000001274770366500132755ustar00rootroot00000000000000luv-1.9.1-0/src/async.c000066400000000000000000000041771274770366500145670ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "luv.h" #include "lthreadpool.h" static uv_async_t* luv_check_async(lua_State* L, int index) { uv_async_t* handle = (uv_async_t*)luv_checkudata(L, index, "uv_async"); luaL_argcheck(L, handle->type == UV_ASYNC && handle->data, index, "Expected uv_async_t"); return handle; } static void luv_async_cb(uv_async_t* handle) { lua_State* L = luv_state(handle->loop); luv_handle_t* data = (luv_handle_t*)handle->data; int n = luv_thread_arg_push(L, (const luv_thread_arg_t*)data->extra); luv_call_callback(L, data, LUV_ASYNC, n); luv_thread_arg_clear((luv_thread_arg_t*)data->extra); } static int luv_new_async(lua_State* L) { uv_async_t* handle; luv_handle_t* data; int ret; luaL_checktype(L, 1, LUA_TFUNCTION); handle = (uv_async_t*)luv_newuserdata(L, sizeof(*handle)); ret = uv_async_init(luv_loop(L), handle, luv_async_cb); if (ret < 0) { lua_pop(L, 1); return luv_error(L, ret); } data = luv_setup_handle(L); data->extra = (luv_thread_arg_t*)malloc(sizeof(luv_thread_arg_t)); memset(data->extra, 0, sizeof(luv_thread_arg_t)); handle->data = data; luv_check_callback(L, (luv_handle_t*)handle->data, LUV_ASYNC, 1); return 1; } static int luv_async_send(lua_State* L) { int ret; uv_async_t* handle = luv_check_async(L, 1); luv_thread_arg_t* arg = (luv_thread_arg_t *)((luv_handle_t*) handle->data)->extra; luv_thread_arg_set(L, arg, 2, lua_gettop(L), 0); ret = uv_async_send(handle); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } luv-1.9.1-0/src/check.c000066400000000000000000000035271274770366500145250ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "luv.h" static uv_check_t* luv_check_check(lua_State* L, int index) { uv_check_t* handle = (uv_check_t*)luv_checkudata(L, index, "uv_check"); luaL_argcheck(L, handle->type == UV_CHECK && handle->data, index, "Expected uv_check_t"); return handle; } static int luv_new_check(lua_State* L) { uv_check_t* handle = (uv_check_t*)luv_newuserdata(L, sizeof(*handle)); int ret = uv_check_init(luv_loop(L), handle); if (ret < 0) { lua_pop(L, 1); return luv_error(L, ret); } handle->data = luv_setup_handle(L); return 1; } static void luv_check_cb(uv_check_t* handle) { lua_State* L = luv_state(handle->loop); luv_handle_t* data = (luv_handle_t*)handle->data; luv_call_callback(L, data, LUV_CHECK, 0); } static int luv_check_start(lua_State* L) { uv_check_t* handle = luv_check_check(L, 1); int ret; luv_check_callback(L, (luv_handle_t *)handle->data, LUV_CHECK, 2); ret = uv_check_start(handle, luv_check_cb); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_check_stop(lua_State* L) { uv_check_t* handle = luv_check_check(L, 1); int ret = uv_check_stop(handle); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } luv-1.9.1-0/src/constants.c000066400000000000000000000337161274770366500154670ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "luv.h" static int luv_constants(lua_State* L) { lua_newtable(L); // File open bitwise flags O_* #ifdef O_RDONLY lua_pushinteger(L, O_RDONLY); lua_setfield(L, -2, "O_RDONLY"); #endif #ifdef O_WRONLY lua_pushinteger(L, O_WRONLY); lua_setfield(L, -2, "O_WRONLY"); #endif #ifdef O_RDWR lua_pushinteger(L, O_RDWR); lua_setfield(L, -2, "O_RDWR"); #endif #ifdef O_APPEND lua_pushinteger(L, O_APPEND); lua_setfield(L, -2, "O_APPEND"); #endif #ifdef O_CREAT lua_pushinteger(L, O_CREAT); lua_setfield(L, -2, "O_CREAT"); #endif #ifdef O_DSYNC lua_pushinteger(L, O_DSYNC); lua_setfield(L, -2, "O_DSYNC"); #endif #ifdef O_EXCL lua_pushinteger(L, O_EXCL); lua_setfield(L, -2, "O_EXCL"); #endif #ifdef O_EXLOCK lua_pushinteger(L, O_EXLOCK); lua_setfield(L, -2, "O_EXLOCK"); #endif #ifdef O_NOCTTY lua_pushinteger(L, O_NOCTTY); lua_setfield(L, -2, "O_NOCTTY"); #endif #ifdef O_NONBLOCK lua_pushinteger(L, O_NONBLOCK); lua_setfield(L, -2, "O_NONBLOCK"); #endif #ifdef O_RSYNC lua_pushinteger(L, O_RSYNC); lua_setfield(L, -2, "O_RSYNC"); #endif #ifdef O_SYNC lua_pushinteger(L, O_SYNC); lua_setfield(L, -2, "O_SYNC"); #endif #ifdef O_TRUNC lua_pushinteger(L, O_TRUNC); lua_setfield(L, -2, "O_TRUNC"); #endif // Socket types SOCK_* #ifdef SOCK_STREAM lua_pushinteger(L, SOCK_STREAM); lua_setfield(L, -2, "SOCK_STREAM"); #endif #ifdef SOCK_DGRAM lua_pushinteger(L, SOCK_DGRAM); lua_setfield(L, -2, "SOCK_DGRAM"); #endif #ifdef SOCK_SEQPACKET lua_pushinteger(L, SOCK_SEQPACKET); lua_setfield(L, -2, "SOCK_SEQPACKET"); #endif #ifdef SOCK_RAW lua_pushinteger(L, SOCK_RAW); lua_setfield(L, -2, "SOCK_RAW"); #endif #ifdef SOCK_RDM lua_pushinteger(L, SOCK_RDM); lua_setfield(L, -2, "SOCK_RDM"); #endif // AF_* #ifdef AF_UNIX lua_pushinteger(L, AF_UNIX); lua_setfield(L, -2, "AF_UNIX"); #endif #ifdef AF_INET lua_pushinteger(L, AF_INET); lua_setfield(L, -2, "AF_INET"); #endif #ifdef AF_INET6 lua_pushinteger(L, AF_INET6); lua_setfield(L, -2, "AF_INET6"); #endif #ifdef AF_IPX lua_pushinteger(L, AF_IPX); lua_setfield(L, -2, "AF_IPX"); #endif #ifdef AF_NETLINK lua_pushinteger(L, AF_NETLINK); lua_setfield(L, -2, "AF_NETLINK"); #endif #ifdef AF_X25 lua_pushinteger(L, AF_X25); lua_setfield(L, -2, "AF_X25"); #endif #ifdef AF_AX25 lua_pushinteger(L, AF_AX25); lua_setfield(L, -2, "AF_AX25"); #endif #ifdef AF_ATMPVC lua_pushinteger(L, AF_ATMPVC); lua_setfield(L, -2, "AF_ATMPVC"); #endif #ifdef AF_APPLETALK lua_pushinteger(L, AF_APPLETALK); lua_setfield(L, -2, "AF_APPLETALK"); #endif #ifdef AF_PACKET lua_pushinteger(L, AF_PACKET); lua_setfield(L, -2, "AF_PACKET"); #endif // AI_* #ifdef AI_ADDRCONFIG lua_pushinteger(L, AI_ADDRCONFIG); lua_setfield(L, -2, "AI_ADDRCONFIG"); #endif #ifdef AI_V4MAPPED lua_pushinteger(L, AI_V4MAPPED); lua_setfield(L, -2, "AI_V4MAPPED"); #endif #ifdef AI_ALL lua_pushinteger(L, AI_ALL); lua_setfield(L, -2, "AI_ALL"); #endif #ifdef AI_NUMERICHOST lua_pushinteger(L, AI_NUMERICHOST); lua_setfield(L, -2, "AI_NUMERICHOST"); #endif #ifdef AI_PASSIVE lua_pushinteger(L, AI_PASSIVE); lua_setfield(L, -2, "AI_PASSIVE"); #endif #ifdef AI_NUMERICSERV lua_pushinteger(L, AI_NUMERICSERV); lua_setfield(L, -2, "AI_NUMERICSERV"); #endif // Signals #ifdef SIGHUP lua_pushinteger(L, SIGHUP); lua_setfield(L, -2, "SIGHUP"); #endif #ifdef SIGINT lua_pushinteger(L, SIGINT); lua_setfield(L, -2, "SIGINT"); #endif #ifdef SIGQUIT lua_pushinteger(L, SIGQUIT); lua_setfield(L, -2, "SIGQUIT"); #endif #ifdef SIGILL lua_pushinteger(L, SIGILL); lua_setfield(L, -2, "SIGILL"); #endif #ifdef SIGTRAP lua_pushinteger(L, SIGTRAP); lua_setfield(L, -2, "SIGTRAP"); #endif #ifdef SIGABRT lua_pushinteger(L, SIGABRT); lua_setfield(L, -2, "SIGABRT"); #endif #ifdef SIGIOT lua_pushinteger(L, SIGIOT); lua_setfield(L, -2, "SIGIOT"); #endif #ifdef SIGBUS lua_pushinteger(L, SIGBUS); lua_setfield(L, -2, "SIGBUS"); #endif #ifdef SIGFPE lua_pushinteger(L, SIGFPE); lua_setfield(L, -2, "SIGFPE"); #endif #ifdef SIGKILL lua_pushinteger(L, SIGKILL); lua_setfield(L, -2, "SIGKILL"); #endif #ifdef SIGUSR1 lua_pushinteger(L, SIGUSR1); lua_setfield(L, -2, "SIGUSR1"); #endif #ifdef SIGSEGV lua_pushinteger(L, SIGSEGV); lua_setfield(L, -2, "SIGSEGV"); #endif #ifdef SIGUSR2 lua_pushinteger(L, SIGUSR2); lua_setfield(L, -2, "SIGUSR2"); #endif #ifdef SIGPIPE lua_pushinteger(L, SIGPIPE); lua_setfield(L, -2, "SIGPIPE"); #endif #ifdef SIGALRM lua_pushinteger(L, SIGALRM); lua_setfield(L, -2, "SIGALRM"); #endif #ifdef SIGTERM lua_pushinteger(L, SIGTERM); lua_setfield(L, -2, "SIGTERM"); #endif #ifdef SIGCHLD lua_pushinteger(L, SIGCHLD); lua_setfield(L, -2, "SIGCHLD"); #endif #ifdef SIGSTKFLT lua_pushinteger(L, SIGSTKFLT); lua_setfield(L, -2, "SIGSTKFLT"); #endif #ifdef SIGCONT lua_pushinteger(L, SIGCONT); lua_setfield(L, -2, "SIGCONT"); #endif #ifdef SIGSTOP lua_pushinteger(L, SIGSTOP); lua_setfield(L, -2, "SIGSTOP"); #endif #ifdef SIGTSTP lua_pushinteger(L, SIGTSTP); lua_setfield(L, -2, "SIGTSTP"); #endif #ifdef SIGBREAK lua_pushinteger(L, SIGBREAK); lua_setfield(L, -2, "SIGBREAK"); #endif #ifdef SIGTTIN lua_pushinteger(L, SIGTTIN); lua_setfield(L, -2, "SIGTTIN"); #endif #ifdef SIGTTOU lua_pushinteger(L, SIGTTOU); lua_setfield(L, -2, "SIGTTOU"); #endif #ifdef SIGURG lua_pushinteger(L, SIGURG); lua_setfield(L, -2, "SIGURG"); #endif #ifdef SIGXCPU lua_pushinteger(L, SIGXCPU); lua_setfield(L, -2, "SIGXCPU"); #endif #ifdef SIGXFSZ lua_pushinteger(L, SIGXFSZ); lua_setfield(L, -2, "SIGXFSZ"); #endif #ifdef SIGVTALRM lua_pushinteger(L, SIGVTALRM); lua_setfield(L, -2, "SIGVTALRM"); #endif #ifdef SIGPROF lua_pushinteger(L, SIGPROF); lua_setfield(L, -2, "SIGPROF"); #endif #ifdef SIGWINCH lua_pushinteger(L, SIGWINCH); lua_setfield(L, -2, "SIGWINCH"); #endif #ifdef SIGIO lua_pushinteger(L, SIGIO); lua_setfield(L, -2, "SIGIO"); #endif #ifdef SIGPOLL lua_pushinteger(L, SIGPOLL); lua_setfield(L, -2, "SIGPOLL"); #endif #ifdef SIGLOST lua_pushinteger(L, SIGLOST); lua_setfield(L, -2, "SIGLOST"); #endif #ifdef SIGPWR lua_pushinteger(L, SIGPWR); lua_setfield(L, -2, "SIGPWR"); #endif #ifdef SIGSYS lua_pushinteger(L, SIGSYS); lua_setfield(L, -2, "SIGSYS"); #endif return 1; } static int luv_af_string_to_num(const char* string) { if (!string) return AF_UNSPEC; #ifdef AF_UNIX if (strcmp(string, "unix") == 0) return AF_UNIX; #endif #ifdef AF_INET if (strcmp(string, "inet") == 0) return AF_INET; #endif #ifdef AF_INET6 if (strcmp(string, "inet6") == 0) return AF_INET6; #endif #ifdef AF_IPX if (strcmp(string, "ipx") == 0) return AF_IPX; #endif #ifdef AF_NETLINK if (strcmp(string, "netlink") == 0) return AF_NETLINK; #endif #ifdef AF_X25 if (strcmp(string, "x25") == 0) return AF_X25; #endif #ifdef AF_AX25 if (strcmp(string, "ax25") == 0) return AF_AX25; #endif #ifdef AF_ATMPVC if (strcmp(string, "atmpvc") == 0) return AF_ATMPVC; #endif #ifdef AF_APPLETALK if (strcmp(string, "appletalk") == 0) return AF_APPLETALK; #endif #ifdef AF_PACKET if (strcmp(string, "packet") == 0) return AF_PACKET; #endif return 0; } static const char* luv_af_num_to_string(const int num) { switch (num) { #ifdef AF_UNIX case AF_UNIX: return "unix"; #endif #ifdef AF_INET case AF_INET: return "inet"; #endif #ifdef AF_INET6 case AF_INET6: return "inet6"; #endif #ifdef AF_IPX case AF_IPX: return "ipx"; #endif #ifdef AF_NETLINK case AF_NETLINK: return "netlink"; #endif #ifdef AF_X25 case AF_X25: return "x25"; #endif #ifdef AF_AX25 case AF_AX25: return "ax25"; #endif #ifdef AF_ATMPVC case AF_ATMPVC: return "atmpvc"; #endif #ifdef AF_APPLETALK case AF_APPLETALK: return "appletalk"; #endif #ifdef AF_PACKET case AF_PACKET: return "packet"; #endif } return NULL; } static int luv_sock_string_to_num(const char* string) { if (!string) return 0; #ifdef SOCK_STREAM if (strcmp(string, "stream") == 0) return SOCK_STREAM; #endif #ifdef SOCK_DGRAM if (strcmp(string, "dgram") == 0) return SOCK_DGRAM; #endif #ifdef SOCK_SEQPACKET if (strcmp(string, "seqpacket") == 0) return SOCK_SEQPACKET; #endif #ifdef SOCK_RAW if (strcmp(string, "raw") == 0) return SOCK_RAW; #endif #ifdef SOCK_RDM if (strcmp(string, "rdm") == 0) return SOCK_RDM; #endif return 0; } static const char* luv_sock_num_to_string(const int num) { switch (num) { #ifdef SOCK_STREAM case SOCK_STREAM: return "stream"; #endif #ifdef SOCK_DGRAM case SOCK_DGRAM: return "dgram"; #endif #ifdef SOCK_SEQPACKET case SOCK_SEQPACKET: return "seqpacket"; #endif #ifdef SOCK_RAW case SOCK_RAW: return "raw"; #endif #ifdef SOCK_RDM case SOCK_RDM: return "rdm"; #endif } return NULL; } static int luv_sig_string_to_num(const char* string) { if (!string) return 0; #ifdef SIGHUP if (strcmp(string, "sighup") == 0) return SIGHUP; #endif #ifdef SIGINT if (strcmp(string, "sigint") == 0) return SIGINT; #endif #ifdef SIGQUIT if (strcmp(string, "sigquit") == 0) return SIGQUIT; #endif #ifdef SIGILL if (strcmp(string, "sigill") == 0) return SIGILL; #endif #ifdef SIGTRAP if (strcmp(string, "sigtrap") == 0) return SIGTRAP; #endif #ifdef SIGABRT if (strcmp(string, "sigabrt") == 0) return SIGABRT; #endif #ifdef SIGIOT if (strcmp(string, "sigiot") == 0) return SIGIOT; #endif #ifdef SIGBUS if (strcmp(string, "sigbus") == 0) return SIGBUS; #endif #ifdef SIGFPE if (strcmp(string, "sigfpe") == 0) return SIGFPE; #endif #ifdef SIGKILL if (strcmp(string, "sigkill") == 0) return SIGKILL; #endif #ifdef SIGUSR1 if (strcmp(string, "sigusr1") == 0) return SIGUSR1; #endif #ifdef SIGSEGV if (strcmp(string, "sigsegv") == 0) return SIGSEGV; #endif #ifdef SIGUSR2 if (strcmp(string, "sigusr2") == 0) return SIGUSR2; #endif #ifdef SIGPIPE if (strcmp(string, "sigpipe") == 0) return SIGPIPE; #endif #ifdef SIGALRM if (strcmp(string, "sigalrm") == 0) return SIGALRM; #endif #ifdef SIGTERM if (strcmp(string, "sigterm") == 0) return SIGTERM; #endif #ifdef SIGCHLD if (strcmp(string, "sigchld") == 0) return SIGCHLD; #endif #ifdef SIGSTKFLT if (strcmp(string, "sigstkflt") == 0) return SIGSTKFLT; #endif #ifdef SIGCONT if (strcmp(string, "sigcont") == 0) return SIGCONT; #endif #ifdef SIGSTOP if (strcmp(string, "sigstop") == 0) return SIGSTOP; #endif #ifdef SIGTSTP if (strcmp(string, "sigtstp") == 0) return SIGTSTP; #endif #ifdef SIGBREAK if (strcmp(string, "sigbreak") == 0) return SIGBREAK; #endif #ifdef SIGTTIN if (strcmp(string, "sigttin") == 0) return SIGTTIN; #endif #ifdef SIGTTOU if (strcmp(string, "sigttou") == 0) return SIGTTOU; #endif #ifdef SIGURG if (strcmp(string, "sigurg") == 0) return SIGURG; #endif #ifdef SIGXCPU if (strcmp(string, "sigxcpu") == 0) return SIGXCPU; #endif #ifdef SIGXFSZ if (strcmp(string, "sigxfsz") == 0) return SIGXFSZ; #endif #ifdef SIGVTALRM if (strcmp(string, "sigvtalrm") == 0) return SIGVTALRM; #endif #ifdef SIGPROF if (strcmp(string, "sigprof") == 0) return SIGPROF; #endif #ifdef SIGWINCH if (strcmp(string, "sigwinch") == 0) return SIGWINCH; #endif #ifdef SIGIO if (strcmp(string, "sigio") == 0) return SIGIO; #endif #ifdef SIGPOLL if (strcmp(string, "sigpoll") == 0) return SIGPOLL; #endif #ifdef SIGLOST if (strcmp(string, "siglost") == 0) return SIGLOST; #endif #ifdef SIGPWR if (strcmp(string, "sigpwr") == 0) return SIGPWR; #endif #ifdef SIGSYS if (strcmp(string, "sigsys") == 0) return SIGSYS; #endif return 0; } static const char* luv_sig_num_to_string(const int num) { switch (num) { #ifdef SIGHUP case SIGHUP: return "sighup"; #endif #ifdef SIGINT case SIGINT: return "sigint"; #endif #ifdef SIGQUIT case SIGQUIT: return "sigquit"; #endif #ifdef SIGILL case SIGILL: return "sigill"; #endif #ifdef SIGTRAP case SIGTRAP: return "sigtrap"; #endif #ifdef SIGABRT case SIGABRT: return "sigabrt"; #endif #ifdef SIGIOT # if SIGIOT != SIGABRT case SIGIOT: return "sigiot"; # endif #endif #ifdef SIGBUS case SIGBUS: return "sigbus"; #endif #ifdef SIGFPE case SIGFPE: return "sigfpe"; #endif #ifdef SIGKILL case SIGKILL: return "sigkill"; #endif #ifdef SIGUSR1 case SIGUSR1: return "sigusr1"; #endif #ifdef SIGSEGV case SIGSEGV: return "sigsegv"; #endif #ifdef SIGUSR2 case SIGUSR2: return "sigusr2"; #endif #ifdef SIGPIPE case SIGPIPE: return "sigpipe"; #endif #ifdef SIGALRM case SIGALRM: return "sigalrm"; #endif #ifdef SIGTERM case SIGTERM: return "sigterm"; #endif #ifdef SIGCHLD case SIGCHLD: return "sigchld"; #endif #ifdef SIGSTKFLT case SIGSTKFLT: return "sigstkflt"; #endif #ifdef SIGCONT case SIGCONT: return "sigcont"; #endif #ifdef SIGSTOP case SIGSTOP: return "sigstop"; #endif #ifdef SIGTSTP case SIGTSTP: return "sigtstp"; #endif #ifdef SIGBREAK case SIGBREAK: return "sigbreak"; #endif #ifdef SIGTTIN case SIGTTIN: return "sigttin"; #endif #ifdef SIGTTOU case SIGTTOU: return "sigttou"; #endif #ifdef SIGURG case SIGURG: return "sigurg"; #endif #ifdef SIGXCPU case SIGXCPU: return "sigxcpu"; #endif #ifdef SIGXFSZ case SIGXFSZ: return "sigxfsz"; #endif #ifdef SIGVTALRM case SIGVTALRM: return "sigvtalrm"; #endif #ifdef SIGPROF case SIGPROF: return "sigprof"; #endif #ifdef SIGWINCH case SIGWINCH: return "sigwinch"; #endif #ifdef SIGIO case SIGIO: return "sigio"; #endif #ifdef SIGPOLL # if SIGPOLL != SIGIO case SIGPOLL: return "sigpoll"; # endif #endif #ifdef SIGLOST case SIGLOST: return "siglost"; #endif #ifdef SIGPWR # if SIGPWR != SIGLOST case SIGPWR: return "sigpwr"; # endif #endif #ifdef SIGSYS case SIGSYS: return "sigsys"; #endif } return NULL; } luv-1.9.1-0/src/dns.c000066400000000000000000000205471274770366500142350ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "luv.h" #ifndef WIN32 #include #include #include #endif static void luv_pushaddrinfo(lua_State* L, struct addrinfo* res) { char ip[INET6_ADDRSTRLEN]; int port, i = 0; const char *addr; struct addrinfo* curr = res; lua_newtable(L); for (curr = res; curr; curr = curr->ai_next) { if (curr->ai_family == AF_INET || curr->ai_family == AF_INET6) { lua_newtable(L); if (curr->ai_family == AF_INET) { addr = (char*) &((struct sockaddr_in*) curr->ai_addr)->sin_addr; port = ((struct sockaddr_in*) curr->ai_addr)->sin_port; } else { addr = (char*) &((struct sockaddr_in6*) curr->ai_addr)->sin6_addr; port = ((struct sockaddr_in6*) curr->ai_addr)->sin6_port; } lua_pushstring(L, luv_af_num_to_string(curr->ai_family)); lua_setfield(L, -2, "family"); uv_inet_ntop(curr->ai_family, addr, ip, INET6_ADDRSTRLEN); lua_pushstring(L, ip); lua_setfield(L, -2, "addr"); if (ntohs(port)) { lua_pushinteger(L, ntohs(port)); lua_setfield(L, -2, "port"); } lua_pushstring(L, luv_sock_num_to_string(curr->ai_socktype)); lua_setfield(L, -2, "socktype"); lua_pushstring(L, luv_af_num_to_string(curr->ai_protocol)); lua_setfield(L, -2, "protocol"); if (curr->ai_canonname) { lua_pushstring(L, curr->ai_canonname); lua_setfield(L, -2, "canonname"); } lua_rawseti(L, -2, ++i); } } } static void luv_getaddrinfo_cb(uv_getaddrinfo_t* req, int status, struct addrinfo* res) { lua_State* L = luv_state(req->loop); int nargs; if (status < 0) { luv_status(L, status); nargs = 1; } else { lua_pushnil(L); luv_pushaddrinfo(L, res); nargs = 2; } luv_fulfill_req(L, (luv_req_t*)req->data, nargs); luv_cleanup_req(L, (luv_req_t*)req->data); req->data = NULL; if (res) uv_freeaddrinfo(res); } static int luv_getaddrinfo(lua_State* L) { uv_getaddrinfo_t* req; const char* node; const char* service; struct addrinfo hints_s; struct addrinfo* hints = &hints_s; int ret, ref; if (lua_isnoneornil(L, 1)) node = NULL; else node = luaL_checkstring(L, 1); if (lua_isnoneornil(L, 2)) service = NULL; else service = luaL_checkstring(L, 2); if (!lua_isnoneornil(L, 3)) luaL_checktype(L, 3, LUA_TTABLE); else hints = NULL; if (hints) { // Initialize the hints memset(hints, 0, sizeof(*hints)); // Process the `family` hint. lua_getfield(L, 3, "family"); if (lua_isnumber(L, -1)) { hints->ai_family = lua_tointeger(L, -1); } else if (lua_isstring(L, -1)) { hints->ai_family = luv_af_string_to_num(lua_tostring(L, -1)); } else if (lua_isnil(L, -1)) { hints->ai_family = AF_UNSPEC; } else { luaL_argerror(L, 3, "family hint must be string if set"); } lua_pop(L, 1); // Process `socktype` hint lua_getfield(L, 3, "socktype"); if (lua_isnumber(L, -1)) { hints->ai_socktype = lua_tointeger(L, -1); } else if (lua_isstring(L, -1)) { hints->ai_socktype = luv_sock_string_to_num(lua_tostring(L, -1)); } else if (!lua_isnil(L, -1)) { return luaL_argerror(L, 3, "socktype hint must be string if set"); } lua_pop(L, 1); // Process the `protocol` hint lua_getfield(L, 3, "protocol"); if (lua_isnumber(L, -1)) { hints->ai_protocol = lua_tointeger(L, -1); } else if (lua_isstring(L, -1)) { int protocol = luv_af_string_to_num(lua_tostring(L, -1)); if (protocol) { hints->ai_protocol = protocol; } else { return luaL_argerror(L, 3, "Invalid protocol hint"); } } else if (!lua_isnil(L, -1)) { return luaL_argerror(L, 3, "protocol hint must be string if set"); } lua_pop(L, 1); lua_getfield(L, 3, "addrconfig"); if (lua_toboolean(L, -1)) hints->ai_flags |= AI_ADDRCONFIG; lua_pop(L, 1); #ifdef AI_V4MAPPED lua_getfield(L, 3, "v4mapped"); if (lua_toboolean(L, -1)) hints->ai_flags |= AI_V4MAPPED; lua_pop(L, 1); #endif #ifdef AI_ALL lua_getfield(L, 3, "all"); if (lua_toboolean(L, -1)) hints->ai_flags |= AI_ALL; lua_pop(L, 1); #endif lua_getfield(L, 3, "numerichost"); if (lua_toboolean(L, -1)) hints->ai_flags |= AI_NUMERICHOST; lua_pop(L, 1); lua_getfield(L, 3, "passive"); if (lua_toboolean(L, -1)) hints->ai_flags |= AI_PASSIVE; lua_pop(L, 1); lua_getfield(L, 3, "numericserv"); if (lua_toboolean(L, -1)) { hints->ai_flags |= AI_NUMERICSERV; /* On OS X upto at least OSX 10.9, getaddrinfo crashes * if AI_NUMERICSERV is set and the servname is NULL or "0". * This workaround avoids a segfault in libsystem. */ if (NULL == service) service = "00"; } lua_pop(L, 1); lua_getfield(L, 3, "canonname"); if (lua_toboolean(L, -1)) hints->ai_flags |= AI_CANONNAME; lua_pop(L, 1); } ref = luv_check_continuation(L, 4); req = (uv_getaddrinfo_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); ret = uv_getaddrinfo(luv_loop(L), req, ref == LUA_NOREF ? NULL : luv_getaddrinfo_cb, node, service, hints); if (ret < 0) { luv_cleanup_req(L, (luv_req_t*)req->data); lua_pop(L, 1); return luv_error(L, ret); } if (ref == LUA_NOREF) { lua_pop(L, 1); luv_pushaddrinfo(L, req->addrinfo); uv_freeaddrinfo(req->addrinfo); luv_cleanup_req(L, (luv_req_t*)req->data); } return 1; } static void luv_getnameinfo_cb(uv_getnameinfo_t* req, int status, const char* hostname, const char* service) { lua_State* L = luv_state(req->loop); int nargs; if (status < 0) { luv_status(L, status); nargs = 1; } else { lua_pushnil(L); lua_pushstring(L, hostname); lua_pushstring(L, service); nargs = 3; } luv_fulfill_req(L, (luv_req_t*)req->data, nargs); luv_cleanup_req(L, (luv_req_t*)req->data); req->data = NULL; } static int luv_getnameinfo(lua_State* L) { uv_getnameinfo_t* req; struct sockaddr_storage addr; const char* ip = NULL; int flags = 0; int ret, ref, port = 0; luaL_checktype(L, 1, LUA_TTABLE); memset(&addr, 0, sizeof(addr)); lua_getfield(L, 1, "ip"); if (lua_isstring(L, -1)) { ip = lua_tostring(L, -1); } else if (!lua_isnil(L, -1)) { luaL_argerror(L, 1, "ip property must be string if set"); } lua_pop(L, 1); lua_getfield(L, 1, "port"); if (lua_isnumber(L, -1)) { port = lua_tointeger(L, -1); } else if (!lua_isnil(L, -1)) { luaL_argerror(L, 1, "port property must be integer if set"); } lua_pop(L, 1); if (ip || port) { if (!ip) ip = "0.0.0.0"; if (!uv_ip4_addr(ip, port, (struct sockaddr_in*)&addr)) { addr.ss_family = AF_INET; } else if (!uv_ip6_addr(ip, port, (struct sockaddr_in6*)&addr)) { addr.ss_family = AF_INET6; } else { return luaL_argerror(L, 1, "Invalid ip address or port"); } } lua_getfield(L, 1, "family"); if (lua_isnumber(L, -1)) { addr.ss_family = lua_tointeger(L, -1); } else if (lua_isstring(L, -1)) { addr.ss_family = luv_af_string_to_num(lua_tostring(L, -1)); } else if (!lua_isnil(L, -1)) { luaL_argerror(L, 1, "family must be string if set"); } lua_pop(L, 1); ref = luv_check_continuation(L, 2); req = (uv_getnameinfo_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); ret = uv_getnameinfo(luv_loop(L), req, ref == LUA_NOREF ? NULL : luv_getnameinfo_cb, (struct sockaddr*)&addr, flags); if (ret < 0) { luv_cleanup_req(L, (luv_req_t*)req->data); lua_pop(L, 1); return luv_error(L, ret); } if (ref == LUA_NOREF) { lua_pop(L, 1); lua_pushstring(L, req->host); lua_pushstring(L, req->service); luv_cleanup_req(L, (luv_req_t*)req->data); return 2; } return 1; } luv-1.9.1-0/src/fs.c000066400000000000000000000465721274770366500140670ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "luv.h" static uv_fs_t* luv_check_fs(lua_State* L, int index) { uv_fs_t* req = (uv_fs_t*)luaL_checkudata(L, index, "uv_req"); luaL_argcheck(L, req->type = (uv_req_type)(UV_FS && req->data), index, "Expected uv_fs_t"); return req; } static void luv_push_timespec_table(lua_State* L, const uv_timespec_t* t) { lua_createtable(L, 0, 2); lua_pushinteger(L, t->tv_sec); lua_setfield(L, -2, "sec"); lua_pushinteger(L, t->tv_nsec); lua_setfield(L, -2, "nsec"); } static void luv_push_stats_table(lua_State* L, const uv_stat_t* s) { const char* type = NULL; lua_createtable(L, 0, 23); lua_pushinteger(L, s->st_dev); lua_setfield(L, -2, "dev"); lua_pushinteger(L, s->st_mode); lua_setfield(L, -2, "mode"); lua_pushinteger(L, s->st_nlink); lua_setfield(L, -2, "nlink"); lua_pushinteger(L, s->st_uid); lua_setfield(L, -2, "uid"); lua_pushinteger(L, s->st_gid); lua_setfield(L, -2, "gid"); lua_pushinteger(L, s->st_rdev); lua_setfield(L, -2, "rdev"); lua_pushinteger(L, s->st_ino); lua_setfield(L, -2, "ino"); lua_pushinteger(L, s->st_size); lua_setfield(L, -2, "size"); lua_pushinteger(L, s->st_blksize); lua_setfield(L, -2, "blksize"); lua_pushinteger(L, s->st_blocks); lua_setfield(L, -2, "blocks"); lua_pushinteger(L, s->st_flags); lua_setfield(L, -2, "flags"); lua_pushinteger(L, s->st_gen); lua_setfield(L, -2, "gen"); luv_push_timespec_table(L, &s->st_atim); lua_setfield(L, -2, "atime"); luv_push_timespec_table(L, &s->st_mtim); lua_setfield(L, -2, "mtime"); luv_push_timespec_table(L, &s->st_ctim); lua_setfield(L, -2, "ctime"); luv_push_timespec_table(L, &s->st_birthtim); lua_setfield(L, -2, "birthtime"); if (S_ISREG(s->st_mode)) { type = "file"; } else if (S_ISDIR(s->st_mode)) { type = "directory"; } else if (S_ISLNK(s->st_mode)) { type = "link"; } else if (S_ISFIFO(s->st_mode)) { type = "fifo"; } #ifdef S_ISSOCK else if (S_ISSOCK(s->st_mode)) { type = "socket"; } #endif else if (S_ISCHR(s->st_mode)) { type = "char"; } else if (S_ISBLK(s->st_mode)) { type = "block"; } if (type) { lua_pushstring(L, type); lua_setfield(L, -2, "type"); } } static int luv_check_flags(lua_State* L, int index) { const char* string; if (lua_isnumber(L, index)) { return lua_tointeger(L, index); } else if (!lua_isstring(L, index)) { return luaL_argerror(L, index, "Expected string or integer for file open mode"); } string = lua_tostring(L, index); if (strcmp(string, "r") == 0) return O_RDONLY; #ifdef O_SYNC if (strcmp(string, "rs") == 0 || strcmp(string, "sr") == 0) return O_RDONLY | O_SYNC; #endif if (strcmp(string, "r+") == 0) return O_RDWR; #ifdef O_SYNC if (strcmp(string, "rs+") == 0 || strcmp(string, "sr+") == 0) return O_RDWR | O_SYNC; #endif if (strcmp(string, "w") == 0) return O_TRUNC | O_CREAT | O_WRONLY; if (strcmp(string, "wx") == 0 || strcmp(string, "xw") == 0) return O_TRUNC | O_CREAT | O_WRONLY | O_EXCL; if (strcmp(string, "w+") == 0) return O_TRUNC | O_CREAT | O_RDWR; if (strcmp(string, "wx+") == 0 || strcmp(string, "xw+") == 0) return O_TRUNC | O_CREAT | O_RDWR | O_EXCL; if (strcmp(string, "a") == 0) return O_APPEND | O_CREAT | O_WRONLY; if (strcmp(string, "ax") == 0 || strcmp(string, "xa") == 0) return O_APPEND | O_CREAT | O_WRONLY | O_EXCL; if (strcmp(string, "a+") == 0) return O_APPEND | O_CREAT | O_RDWR; if (strcmp(string, "ax+") == 0 || strcmp(string, "xa+") == 0) return O_APPEND | O_CREAT | O_RDWR | O_EXCL; return luaL_error(L, "Unknown file open flag '%s'", string); } static int luv_check_amode(lua_State* L, int index) { size_t i; int mode; const char* string; if (lua_isnumber(L, index)) { return lua_tointeger(L, index); } else if (!lua_isstring(L, index)) { return luaL_argerror(L, index, "Expected string or integer for file access mode check"); } string = lua_tostring(L, index); mode = 0; for (i = 0; i < strlen(string); ++i) { switch (string[i]) { case 'r': case 'R': mode |= R_OK; break; case 'w': case 'W': mode |= W_OK; break; case 'x': case 'X': mode |= X_OK; break; default: return luaL_argerror(L, index, "Unknown character in access mode string"); } } return mode; } /* Processes a result and pushes the data onto the stack returns the number of items pushed */ static int push_fs_result(lua_State* L, uv_fs_t* req) { luv_req_t* data = (luv_req_t*)req->data; if (req->fs_type == UV_FS_ACCESS) { lua_pushboolean(L, req->result >= 0); return 1; } if (req->result < 0) { lua_pushnil(L); if (req->path) { lua_pushfstring(L, "%s: %s: %s", uv_err_name(req->result), uv_strerror(req->result), req->path); } else { lua_pushfstring(L, "%s: %s", uv_err_name(req->result), uv_strerror(req->result)); } return 2; } switch (req->fs_type) { case UV_FS_CLOSE: case UV_FS_RENAME: case UV_FS_UNLINK: case UV_FS_RMDIR: case UV_FS_MKDIR: case UV_FS_FTRUNCATE: case UV_FS_FSYNC: case UV_FS_FDATASYNC: case UV_FS_LINK: case UV_FS_SYMLINK: case UV_FS_CHMOD: case UV_FS_FCHMOD: case UV_FS_CHOWN: case UV_FS_FCHOWN: case UV_FS_UTIME: case UV_FS_FUTIME: lua_pushboolean(L, 1); return 1; case UV_FS_OPEN: case UV_FS_SENDFILE: case UV_FS_WRITE: lua_pushinteger(L, req->result); return 1; case UV_FS_STAT: case UV_FS_LSTAT: case UV_FS_FSTAT: luv_push_stats_table(L, &req->statbuf); return 1; case UV_FS_MKDTEMP: lua_pushstring(L, req->path); return 1; case UV_FS_READLINK: case UV_FS_REALPATH: lua_pushstring(L, (char*)req->ptr); return 1; case UV_FS_READ: lua_pushlstring(L, (const char*)data->data, req->result); return 1; case UV_FS_SCANDIR: // Expose the userdata for the request. lua_rawgeti(L, LUA_REGISTRYINDEX, data->req_ref); return 1; default: lua_pushnil(L); lua_pushfstring(L, "UNKNOWN FS TYPE %d\n", req->fs_type); return 2; } } static void luv_fs_cb(uv_fs_t* req) { lua_State* L = luv_state(req->loop); int nargs = push_fs_result(L, req); if (nargs == 2 && lua_isnil(L, -nargs)) { // If it was an error, convert to (err, value) format. lua_remove(L, -nargs); nargs--; } else { // Otherwise insert a nil in front to convert to (err, value) format. lua_pushnil(L); lua_insert(L, -nargs - 1); nargs++; } luv_fulfill_req(L, (luv_req_t*)req->data, nargs); if (req->fs_type != UV_FS_SCANDIR) { luv_cleanup_req(L, (luv_req_t*)req->data); req->data = NULL; uv_fs_req_cleanup(req); } } #define FS_CALL(func, req, ...) { \ int ret, sync; \ luv_req_t* data = (luv_req_t*)req->data; \ sync = data->callback_ref == LUA_NOREF; \ ret = uv_fs_##func(luv_loop(L), req, __VA_ARGS__, \ sync ? NULL : luv_fs_cb); \ if (req->fs_type != UV_FS_ACCESS && ret < 0) { \ lua_pushnil(L); \ if (req->path) { \ lua_pushfstring(L, "%s: %s: %s", uv_err_name(req->result), uv_strerror(req->result), req->path); \ } \ else { \ lua_pushfstring(L, "%s: %s", uv_err_name(req->result), uv_strerror(req->result)); \ } \ lua_pushstring(L, uv_err_name(req->result)); \ luv_cleanup_req(L, (luv_req_t*)req->data); \ req->data = NULL; \ uv_fs_req_cleanup(req); \ return 3; \ } \ if (sync) { \ int nargs = push_fs_result(L, req); \ if (req->fs_type != UV_FS_SCANDIR) { \ luv_cleanup_req(L, (luv_req_t*)req->data); \ req->data = NULL; \ uv_fs_req_cleanup(req); \ } \ return nargs; \ } \ lua_rawgeti(L, LUA_REGISTRYINDEX, data->req_ref); \ return 1; \ } static int luv_fs_close(lua_State* L) { uv_file file = luaL_checkinteger(L, 1); int ref = luv_check_continuation(L, 2); uv_fs_t* req = (uv_fs_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(close, req, file); } static int luv_fs_open(lua_State* L) { const char* path = luaL_checkstring(L, 1); int flags = luv_check_flags(L, 2); int mode = luaL_checkinteger(L, 3); int ref = luv_check_continuation(L, 4); uv_fs_t* req = (uv_fs_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(open, req, path, flags, mode); } static int luv_fs_read(lua_State* L) { uv_file file = luaL_checkinteger(L, 1); int64_t len = luaL_checkinteger(L, 2); int64_t offset = luaL_checkinteger(L, 3); uv_buf_t buf; int ref; uv_fs_t* req; char* data = (char*)malloc(len); if (!data) return luaL_error(L, "Failure to allocate buffer"); buf = uv_buf_init(data, len); ref = luv_check_continuation(L, 4); req = (uv_fs_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); // TODO: find out why we can't just use req->ptr for the base ((luv_req_t*)req->data)->data = buf.base; FS_CALL(read, req, file, &buf, 1, offset); } static int luv_fs_unlink(lua_State* L) { const char* path = luaL_checkstring(L, 1); int ref = luv_check_continuation(L, 2); uv_fs_t* req = (uv_fs_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(unlink, req, path); } static int luv_fs_write(lua_State* L) { uv_file file = luaL_checkinteger(L, 1); uv_buf_t buf; int64_t offset; int ref; uv_fs_t* req; size_t count; uv_buf_t *bufs = NULL; if (lua_istable(L, 2)) { bufs = luv_prep_bufs(L, 2, &count); buf.base = NULL; } else if (lua_isstring(L, 2)) { luv_check_buf(L, 2, &buf); count = 1; } else { return luaL_argerror(L, 2, "data must be string or table of strings"); } offset = luaL_checkinteger(L, 3); ref = luv_check_continuation(L, 4); req = (uv_fs_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); req->ptr = buf.base; ((luv_req_t*)req->data)->data = bufs; FS_CALL(write, req, file, bufs ? bufs : &buf, count, offset); } static int luv_fs_mkdir(lua_State* L) { const char* path = luaL_checkstring(L, 1); int mode = luaL_checkinteger(L, 2); int ref = luv_check_continuation(L, 3); uv_fs_t* req = (uv_fs_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(mkdir, req, path, mode); } static int luv_fs_mkdtemp(lua_State* L) { const char* tpl = luaL_checkstring(L, 1); int ref = luv_check_continuation(L, 2); uv_fs_t* req = (uv_fs_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(mkdtemp, req, tpl); } static int luv_fs_rmdir(lua_State* L) { const char* path = luaL_checkstring(L, 1); int ref = luv_check_continuation(L, 2); uv_fs_t* req = (uv_fs_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(rmdir, req, path); } static int luv_fs_scandir(lua_State* L) { const char* path = luaL_checkstring(L, 1); int flags = 0; // TODO: find out what these flags are. int ref = luv_check_continuation(L, 2); uv_fs_t* req = (uv_fs_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(scandir, req, path, flags); } static int luv_fs_scandir_next(lua_State* L) { uv_fs_t* req = luv_check_fs(L, 1); uv_dirent_t ent; int ret = uv_fs_scandir_next(req, &ent); const char* type; if (ret == UV_EOF) { luv_cleanup_req(L, (luv_req_t*)req->data); req->data = NULL; uv_fs_req_cleanup(req); return 0; } if (ret < 0) return luv_error(L, ret); lua_pushstring(L, ent.name); switch (ent.type) { case UV_DIRENT_UNKNOWN: return 1; case UV_DIRENT_FILE: type = "file"; break; case UV_DIRENT_DIR: type = "directory"; break; case UV_DIRENT_LINK: type = "link"; break; case UV_DIRENT_FIFO: type = "fifo"; break; case UV_DIRENT_SOCKET: type = "socket"; break; case UV_DIRENT_CHAR: type = "char"; break; case UV_DIRENT_BLOCK: type = "block"; break; default: type = "unknown"; break; } lua_pushstring(L, type); return 2; } static int luv_fs_stat(lua_State* L) { const char* path = luaL_checkstring(L, 1); int ref = luv_check_continuation(L, 2); uv_fs_t* req = (uv_fs_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(stat, req, path); } static int luv_fs_fstat(lua_State* L) { uv_file file = luaL_checkinteger(L, 1); int ref = luv_check_continuation(L, 2); uv_fs_t* req = (uv_fs_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(fstat, req, file); } static int luv_fs_lstat(lua_State* L) { const char* path = luaL_checkstring(L, 1); int ref = luv_check_continuation(L, 2); uv_fs_t* req = (uv_fs_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(lstat, req, path); } static int luv_fs_rename(lua_State* L) { const char* path = luaL_checkstring(L, 1); const char* new_path = luaL_checkstring(L, 2); int ref = luv_check_continuation(L, 3); uv_fs_t* req = (uv_fs_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(rename, req, path, new_path); } static int luv_fs_fsync(lua_State* L) { uv_file file = luaL_checkinteger(L, 1); int ref = luv_check_continuation(L, 2); uv_fs_t* req = (uv_fs_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(fsync, req, file); } static int luv_fs_fdatasync(lua_State* L) { uv_file file = luaL_checkinteger(L, 1); int ref = luv_check_continuation(L, 2); uv_fs_t* req = (uv_fs_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(fdatasync, req, file); } static int luv_fs_ftruncate(lua_State* L) { uv_file file = luaL_checkinteger(L, 1); int64_t offset = luaL_checkinteger(L, 2); int ref = luv_check_continuation(L, 3); uv_fs_t* req = (uv_fs_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(ftruncate, req, file, offset); } static int luv_fs_sendfile(lua_State* L) { uv_file out_fd = luaL_checkinteger(L, 1); uv_file in_fd = luaL_checkinteger(L, 2); int64_t in_offset = luaL_checkinteger(L, 3); size_t length = luaL_checkinteger(L, 4); int ref = luv_check_continuation(L, 5); uv_fs_t* req = (uv_fs_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(sendfile, req, out_fd, in_fd, in_offset, length); } static int luv_fs_access(lua_State* L) { const char* path = luaL_checkstring(L, 1); int amode = luv_check_amode(L, 2); int ref = luv_check_continuation(L, 3); uv_fs_t* req = (uv_fs_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(access, req, path, amode); } static int luv_fs_chmod(lua_State* L) { const char* path = luaL_checkstring(L, 1); int mode = luaL_checkinteger(L, 2); int ref = luv_check_continuation(L, 3); uv_fs_t* req = (uv_fs_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(chmod, req, path, mode); } static int luv_fs_fchmod(lua_State* L) { uv_file file = luaL_checkinteger(L, 1); int mode = luaL_checkinteger(L, 2); int ref = luv_check_continuation(L, 3); uv_fs_t* req = (uv_fs_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(fchmod, req, file, mode); } static int luv_fs_utime(lua_State* L) { const char* path = luaL_checkstring(L, 1); double atime = luaL_checknumber(L, 2); double mtime = luaL_checknumber(L, 3); int ref = luv_check_continuation(L, 4); uv_fs_t* req = (uv_fs_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(utime, req, path, atime, mtime); } static int luv_fs_futime(lua_State* L) { uv_file file = luaL_checkinteger(L, 1); double atime = luaL_checknumber(L, 2); double mtime = luaL_checknumber(L, 3); int ref = luv_check_continuation(L, 4); uv_fs_t* req = (uv_fs_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(futime, req, file, atime, mtime); } static int luv_fs_link(lua_State* L) { const char* path = luaL_checkstring(L, 1); const char* new_path = luaL_checkstring(L, 2); int ref = luv_check_continuation(L, 3); uv_fs_t* req = (uv_fs_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(link, req, path, new_path); } static int luv_fs_symlink(lua_State* L) { const char* path = luaL_checkstring(L, 1); const char* new_path = luaL_checkstring(L, 2); int flags = 0, ref; uv_fs_t* req; if (lua_type(L, 3) == LUA_TTABLE) { lua_getfield(L, 3, "dir"); if (lua_toboolean(L, -1)) flags |= UV_FS_SYMLINK_DIR; lua_pop(L, 1); lua_getfield(L, 3, "junction"); if (lua_toboolean(L, -1)) flags |= UV_FS_SYMLINK_JUNCTION; lua_pop(L, 1); } ref = luv_check_continuation(L, 4); req = (uv_fs_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(symlink, req, path, new_path, flags); } static int luv_fs_readlink(lua_State* L) { const char* path = luaL_checkstring(L, 1); int ref = luv_check_continuation(L, 2); uv_fs_t* req = (uv_fs_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(readlink, req, path); } static int luv_fs_realpath(lua_State* L) { const char* path = luaL_checkstring(L, 1); int ref = luv_check_continuation(L, 2); uv_fs_t* req = (uv_fs_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(realpath, req, path); } static int luv_fs_chown(lua_State* L) { const char* path = luaL_checkstring(L, 1); uv_uid_t uid = luaL_checkinteger(L, 2); uv_uid_t gid = luaL_checkinteger(L, 3); int ref = luv_check_continuation(L, 4); uv_fs_t* req = (uv_fs_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(chown, req, path, uid, gid); } static int luv_fs_fchown(lua_State* L) { uv_file file = luaL_checkinteger(L, 1); uv_uid_t uid = luaL_checkinteger(L, 2); uv_uid_t gid = luaL_checkinteger(L, 3); int ref = luv_check_continuation(L, 4); uv_fs_t* req = (uv_fs_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(fchown, req, file, uid, gid); } luv-1.9.1-0/src/fs_event.c000066400000000000000000000056631274770366500152640ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "luv.h" static uv_fs_event_t* luv_check_fs_event(lua_State* L, int index) { uv_fs_event_t* handle = (uv_fs_event_t*)luv_checkudata(L, index, "uv_fs_event"); luaL_argcheck(L, handle->type == UV_FS_EVENT && handle->data, index, "Expected uv_fs_event_t"); return handle; } static int luv_new_fs_event(lua_State* L) { uv_fs_event_t* handle = (uv_fs_event_t*)luv_newuserdata(L, sizeof(*handle)); int ret = uv_fs_event_init(luv_loop(L), handle); if (ret < 0) { lua_pop(L, 1); return luv_error(L, ret); } handle->data = luv_setup_handle(L); return 1; } static void luv_fs_event_cb(uv_fs_event_t* handle, const char* filename, int events, int status) { lua_State* L = luv_state(handle->loop); // err luv_status(L, status); // filename lua_pushstring(L, filename); // events lua_newtable(L); if (events & UV_RENAME) { lua_pushboolean(L, 1); lua_setfield(L, -2, "rename"); } if (events & UV_CHANGE) { lua_pushboolean(L, 1); lua_setfield(L, -2, "change"); } luv_call_callback(L, (luv_handle_t*)handle->data, LUV_FS_EVENT, 3); } static int luv_fs_event_start(lua_State* L) { uv_fs_event_t* handle = luv_check_fs_event(L, 1); const char* path = luaL_checkstring(L, 2); int flags = 0, ret; luaL_checktype(L, 3, LUA_TTABLE); lua_getfield(L, 3, "watch_entry"); if (lua_toboolean(L, -1)) flags |= UV_FS_EVENT_WATCH_ENTRY; lua_pop(L, 1); lua_getfield(L, 3, "stat"); if (lua_toboolean(L, -1)) flags |= UV_FS_EVENT_STAT; lua_pop(L, 1); lua_getfield(L, 3, "recursive"); if (lua_toboolean(L, -1)) flags |= UV_FS_EVENT_RECURSIVE; lua_pop(L, 1); luv_check_callback(L, (luv_handle_t*)handle->data, LUV_FS_EVENT, 4); ret = uv_fs_event_start(handle, luv_fs_event_cb, path, flags); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_fs_event_stop(lua_State* L) { uv_fs_event_t* handle = luv_check_fs_event(L, 1); int ret = uv_fs_event_stop(handle); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_fs_event_getpath(lua_State* L) { uv_fs_event_t* handle = luv_check_fs_event(L, 1); size_t len = 2*PATH_MAX; char buf[2*PATH_MAX]; int ret = uv_fs_event_getpath(handle, buf, &len); if (ret < 0) return luv_error(L, ret); lua_pushlstring(L, buf, len); return 1; } luv-1.9.1-0/src/fs_poll.c000066400000000000000000000050301274770366500150750ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "luv.h" static uv_fs_poll_t* luv_check_fs_poll(lua_State* L, int index) { uv_fs_poll_t* handle = (uv_fs_poll_t*)luv_checkudata(L, index, "uv_fs_poll"); luaL_argcheck(L, handle->type == UV_FS_POLL && handle->data, index, "Expected uv_fs_poll_t"); return handle; } static int luv_new_fs_poll(lua_State* L) { uv_fs_poll_t* handle = (uv_fs_poll_t*)luv_newuserdata(L, sizeof(*handle)); int ret = uv_fs_poll_init(luv_loop(L), handle); if (ret < 0) { lua_pop(L, 1); return luv_error(L, ret); } handle->data = luv_setup_handle(L); return 1; } static void luv_fs_poll_cb(uv_fs_poll_t* handle, int status, const uv_stat_t* prev, const uv_stat_t* curr) { lua_State* L = luv_state(handle->loop); // err luv_status(L, status); // prev if (prev) { luv_push_stats_table(L, prev); } else { lua_pushnil(L); } // curr if (curr) { luv_push_stats_table(L, curr); } else { lua_pushnil(L); } luv_call_callback(L, (luv_handle_t*)handle->data, LUV_FS_POLL, 3); } static int luv_fs_poll_start(lua_State* L) { uv_fs_poll_t* handle = luv_check_fs_poll(L, 1); const char* path = luaL_checkstring(L, 2); unsigned int interval = luaL_checkinteger(L, 3); int ret; luv_check_callback(L, (luv_handle_t*)handle->data, LUV_FS_POLL, 4); ret = uv_fs_poll_start(handle, luv_fs_poll_cb, path, interval); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_fs_poll_stop(lua_State* L) { uv_fs_poll_t* handle = luv_check_fs_poll(L, 1); int ret = uv_fs_poll_stop(handle); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_fs_poll_getpath(lua_State* L) { uv_fs_poll_t* handle = luv_check_fs_poll(L, 1); size_t len = 2*PATH_MAX; char buf[2*PATH_MAX]; int ret = uv_fs_poll_getpath(handle, buf, &len); if (ret < 0) return luv_error(L, ret); lua_pushlstring(L, buf, len); return 1; } luv-1.9.1-0/src/handle.c000066400000000000000000000116571274770366500147060ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "luv.h" static void* luv_newuserdata(lua_State* L, size_t sz) { void* handle = malloc(sz); if (handle) { *(void**)lua_newuserdata(L, sizeof(void*)) = handle; } return handle; } static void* luv_checkudata(lua_State* L, int ud, const char* tname) { return *(void**) luaL_checkudata(L, ud, tname); } static uv_handle_t* luv_check_handle(lua_State* L, int index) { int isHandle; uv_handle_t* handle; if (!(handle = *(uv_handle_t**)lua_touserdata(L, index))) { goto fail; } if (!handle->data) { goto fail; } lua_getfield(L, LUA_REGISTRYINDEX, "uv_handle"); lua_getmetatable(L, index < 0 ? index - 1 : index); lua_rawget(L, -2); isHandle = lua_toboolean(L, -1); lua_pop(L, 2); if (isHandle) { return handle; } fail: luaL_argerror(L, index, "Expected uv_handle userdata"); return NULL; } // Show the libuv type instead of generic "userdata" static int luv_handle_tostring(lua_State* L) { uv_handle_t* handle = luv_check_handle(L, 1); switch (handle->type) { #define XX(uc, lc) case UV_##uc: lua_pushfstring(L, "uv_"#lc"_t: %p", handle); break; UV_HANDLE_TYPE_MAP(XX) #undef XX default: lua_pushfstring(L, "uv_handle_t: %p", handle); break; } return 1; } static int luv_is_active(lua_State* L) { uv_handle_t* handle = luv_check_handle(L, 1); int ret = uv_is_active(handle); if (ret < 0) return luv_error(L, ret); lua_pushboolean(L, ret); return 1; } static int luv_is_closing(lua_State* L) { uv_handle_t* handle = luv_check_handle(L, 1); int ret = uv_is_closing(handle); if (ret < 0) return luv_error(L, ret); lua_pushboolean(L, ret); return 1; } static void luv_close_cb(uv_handle_t* handle) { lua_State* L = luv_state(handle->loop); luv_handle_t* data = (luv_handle_t*)handle->data; if (!data) return; luv_call_callback(L, data, LUV_CLOSED, 0); luv_unref_handle(L, data); } static int luv_close(lua_State* L) { uv_handle_t* handle = luv_check_handle(L, 1); if (uv_is_closing(handle)) { luaL_error(L, "handle %p is already closing", handle); } if (!lua_isnoneornil(L, 2)) { luv_check_callback(L, (luv_handle_t*)handle->data, LUV_CLOSED, 2); } uv_close(handle, luv_close_cb); return 0; } static void luv_handle_free(uv_handle_t* handle) { luv_handle_t* data = handle->data; if (data) { free(data->extra); free(data); } free(handle); } static void luv_gc_cb(uv_handle_t* handle) { luv_close_cb(handle); luv_handle_free(handle); } static int luv_handle_gc(lua_State* L) { uv_handle_t** udata = (uv_handle_t**)lua_touserdata(L, 1); uv_handle_t* handle = *udata; // Only cleanup if the handle hasn't been cleaned up yet. if (handle) { if (!uv_is_closing(handle)) { // If the handle is not closed yet, close it first before freeing memory. uv_close(handle, luv_gc_cb); } else { // Otherwise, free the memory right away. luv_handle_free(handle); } // Mark as cleaned up by wiping the dangling pointer. *udata = NULL; } return 0; } static int luv_ref(lua_State* L) { uv_handle_t* handle = luv_check_handle(L, 1); uv_ref(handle); return 0; } static int luv_unref(lua_State* L) { uv_handle_t* handle = luv_check_handle(L, 1); uv_unref(handle); return 0; } static int luv_has_ref(lua_State* L) { uv_handle_t* handle = luv_check_handle(L, 1); int ret = uv_has_ref(handle); if (ret < 0) return luv_error(L, ret); lua_pushboolean(L, ret); return 1; } static int luv_send_buffer_size(lua_State* L) { uv_handle_t* handle = luv_check_handle(L, 1); int value; int ret; if (lua_isnoneornil(L, 2)) { value = 0; } else { value = luaL_checkinteger(L, 2); } ret = uv_send_buffer_size(handle, &value); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_recv_buffer_size(lua_State* L) { uv_handle_t* handle = luv_check_handle(L, 1); int value; int ret; if (lua_isnoneornil(L, 2)) { value = 0; } else { value = luaL_checkinteger(L, 2); } ret = uv_recv_buffer_size(handle, &value); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_fileno(lua_State* L) { uv_handle_t* handle = luv_check_handle(L, 1); uv_os_fd_t fd; int ret = uv_fileno(handle, &fd); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, (LUA_INTEGER)(ptrdiff_t)fd); return 1; } luv-1.9.1-0/src/idle.c000066400000000000000000000034771274770366500143710ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "luv.h" static uv_idle_t* luv_check_idle(lua_State* L, int index) { uv_idle_t* handle = (uv_idle_t*)luv_checkudata(L, index, "uv_idle"); luaL_argcheck(L, handle->type == UV_IDLE && handle->data, index, "Expected uv_idle_t"); return handle; } static int luv_new_idle(lua_State* L) { uv_idle_t* handle = (uv_idle_t*)luv_newuserdata(L, sizeof(*handle)); int ret = uv_idle_init(luv_loop(L), handle); if (ret < 0) { lua_pop(L, 1); return luv_error(L, ret); } handle->data = luv_setup_handle(L); return 1; } static void luv_idle_cb(uv_idle_t* handle) { lua_State* L = luv_state(handle->loop); luv_handle_t* data = (luv_handle_t*)handle->data; luv_call_callback(L, data, LUV_IDLE, 0); } static int luv_idle_start(lua_State* L) { uv_idle_t* handle = luv_check_idle(L, 1); int ret; luv_check_callback(L, (luv_handle_t *)handle->data, LUV_IDLE, 2); ret = uv_idle_start(handle, luv_idle_cb); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_idle_stop(lua_State* L) { uv_idle_t* handle = luv_check_idle(L, 1); int ret = uv_idle_stop(handle); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } luv-1.9.1-0/src/lhandle.c000066400000000000000000000064171274770366500150600ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "lhandle.h" static luv_handle_t* luv_setup_handle(lua_State* L) { luv_handle_t* data; const uv_handle_t* handle = *(uv_handle_t**)lua_touserdata(L, -1); luaL_checktype(L, -1, LUA_TUSERDATA); data = (luv_handle_t*)malloc(sizeof(*data)); if (!data) luaL_error(L, "Can't allocate luv handle"); #define XX(uc, lc) case UV_##uc: \ luaL_getmetatable(L, "uv_"#lc); \ break; switch (handle->type) { UV_HANDLE_TYPE_MAP(XX) default: luaL_error(L, "Unknown handle type"); return NULL; } #undef XX lua_setmetatable(L, -2); lua_pushvalue(L, -1); data->ref = luaL_ref(L, LUA_REGISTRYINDEX); data->callbacks[0] = LUA_NOREF; data->callbacks[1] = LUA_NOREF; data->extra = NULL; return data; } static void luv_check_callback(lua_State* L, luv_handle_t* data, luv_callback_id id, int index) { luaL_checktype(L, index, LUA_TFUNCTION); luaL_unref(L, LUA_REGISTRYINDEX, data->callbacks[id]); lua_pushvalue(L, index); data->callbacks[id] = luaL_ref(L, LUA_REGISTRYINDEX); } static int traceback (lua_State *L) { if (!lua_isstring(L, 1)) /* 'message' not a string? */ return 1; /* keep it intact */ lua_pushglobaltable(L); lua_getfield(L, -1, "debug"); lua_remove(L, -2); if (!lua_istable(L, -1)) { lua_pop(L, 1); return 1; } lua_getfield(L, -1, "traceback"); if (!lua_isfunction(L, -1)) { lua_pop(L, 2); return 1; } lua_pushvalue(L, 1); /* pass error message */ lua_pushinteger(L, 2); /* skip this function and traceback */ lua_call(L, 2, 1); /* call debug.traceback */ return 1; } static void luv_call_callback(lua_State* L, luv_handle_t* data, luv_callback_id id, int nargs) { int ref = data->callbacks[id]; if (ref == LUA_NOREF) { lua_pop(L, nargs); } else { // Get the traceback function in case of error lua_pushcfunction(L, traceback); // And insert it before the args if there are any. if (nargs) { lua_insert(L, -1 - nargs); } // Get the callback lua_rawgeti(L, LUA_REGISTRYINDEX, ref); // And insert it before the args if there are any. if (nargs) { lua_insert(L, -1 - nargs); } if (lua_pcall(L, nargs, 0, -2 - nargs)) { fprintf(stderr, "Uncaught Error: %s\n", lua_tostring(L, -1)); exit(-1); } // Remove the traceback function lua_pop(L, 1); } } static void luv_unref_handle(lua_State* L, luv_handle_t* data) { luaL_unref(L, LUA_REGISTRYINDEX, data->ref); luaL_unref(L, LUA_REGISTRYINDEX, data->callbacks[0]); luaL_unref(L, LUA_REGISTRYINDEX, data->callbacks[1]); } static void luv_find_handle(lua_State* L, luv_handle_t* data) { lua_rawgeti(L, LUA_REGISTRYINDEX, data->ref); } luv-1.9.1-0/src/lhandle.h000066400000000000000000000040321274770366500150540ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef LUV_LHANDLE_H #define LUV_LHANDLE_H #include "luv.h" /* There are two slots for holding callbacks. One is for the CLOSED event. The other slot is for all others since they never conflict in practice. */ #define luv_callback_id int #define LUV_CLOSED 0 #define LUV_TIMEOUT 1 #define LUV_PREPARE 1 #define LUV_IDLE 1 #define LUV_CHECK 1 #define LUV_ASYNC 1 #define LUV_POLL 1 #define LUV_SIGNAL 1 #define LUV_EXIT 1 #define LUV_CONNECTION 1 #define LUV_READ 1 #define LUV_RECV 1 #define LUV_FS_EVENT 1 #define LUV_FS_POLL 1 /* Ref for userdata and event callbacks */ typedef struct { int ref; int callbacks[2]; void* extra; } luv_handle_t; /* Setup the handle at the top of the stack */ static luv_handle_t* luv_setup_handle(lua_State* L); /* Store a lua callback in a luv_handle for future callbacks. Either replace an existing callback by id or append a new one at the end. */ static void luv_check_callback(lua_State* L, luv_handle_t* data, luv_callback_id id, int index); /* Lookup a function and call it with nargs If there is no such function, pop the args. */ static void luv_call_callback(lua_State* L, luv_handle_t* data, luv_callback_id id, int nargs); /* Push a userdata on the stack from a handle */ static void luv_find_handle(lua_State* L, luv_handle_t* data); /* Unref the handle from the lua world, allowing it to GC */ static void luv_unref_handle(lua_State* L, luv_handle_t* data); #endif luv-1.9.1-0/src/loop.c000066400000000000000000000047121274770366500144160ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "luv.h" static int luv_loop_close(lua_State* L) { int ret = uv_loop_close(luv_loop(L)); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } // These are the same order as uv_run_mode which also starts at 0 static const char *const luv_runmodes[] = { "default", "once", "nowait", NULL }; static int luv_run(lua_State* L) { int mode = luaL_checkoption(L, 1, "default", luv_runmodes); int ret = uv_run(luv_loop(L), (uv_run_mode)mode); if (ret < 0) return luv_error(L, ret); lua_pushboolean(L, ret); return 1; } static int luv_loop_alive(lua_State* L) { int ret = uv_loop_alive(luv_loop(L)); if (ret < 0) return luv_error(L, ret); lua_pushboolean(L, ret); return 1; } static int luv_stop(lua_State* L) { uv_stop(luv_loop(L)); return 0; } static int luv_backend_fd(lua_State* L) { int ret = uv_backend_fd(luv_loop(L)); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_backend_timeout(lua_State* L) { int ret = uv_backend_timeout(luv_loop(L)); lua_pushinteger(L, ret); return 1; } static int luv_now(lua_State* L) { uint64_t now = uv_now(luv_loop(L)); lua_pushinteger(L, now); return 1; } static int luv_update_time(lua_State* L) { uv_update_time(luv_loop(L)); return 0; } static void luv_walk_cb(uv_handle_t* handle, void* arg) { lua_State* L = (lua_State*)arg; luv_handle_t* data = (luv_handle_t*)handle->data; // Sanity check // Most invalid values are large and refs are small, 0x1000000 is arbitrary. assert(data && data->ref < 0x1000000); lua_pushvalue(L, 1); // Copy the function luv_find_handle(L, data); // Get the userdata lua_call(L, 1, 0); // Call the function } static int luv_walk(lua_State* L) { luaL_checktype(L, 1, LUA_TFUNCTION); uv_walk(luv_loop(L), luv_walk_cb, L); return 0; } luv-1.9.1-0/src/lreq.c000066400000000000000000000040751274770366500144120ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "lreq.h" static int luv_check_continuation(lua_State* L, int index) { if (lua_isnoneornil(L, index)) return LUA_NOREF; luaL_checktype(L, index, LUA_TFUNCTION); lua_pushvalue(L, index); return luaL_ref(L, LUA_REGISTRYINDEX); } // Store a lua callback in a luv_req for the continuation. // The uv_req_t is assumed to be at the top of the stack static luv_req_t* luv_setup_req(lua_State* L, int callback_ref) { luv_req_t* data; luaL_checktype(L, -1, LUA_TUSERDATA); data = (luv_req_t*)malloc(sizeof(*data)); if (!data) luaL_error(L, "Problem allocating luv request"); luaL_getmetatable(L, "uv_req"); lua_setmetatable(L, -2); lua_pushvalue(L, -1); data->req_ref = luaL_ref(L, LUA_REGISTRYINDEX); data->callback_ref = callback_ref; data->data_ref = LUA_NOREF; data->data = NULL; return data; } static void luv_fulfill_req(lua_State* L, luv_req_t* data, int nargs) { if (data->callback_ref == LUA_NOREF) { lua_pop(L, nargs); } else { // Get the callback lua_rawgeti(L, LUA_REGISTRYINDEX, data->callback_ref); // And insert it before the args if there are any. if (nargs) { lua_insert(L, -1 - nargs); } lua_call(L, nargs, 0); } } static void luv_cleanup_req(lua_State* L, luv_req_t* data) { luaL_unref(L, LUA_REGISTRYINDEX, data->req_ref); luaL_unref(L, LUA_REGISTRYINDEX, data->callback_ref); luaL_unref(L, LUA_REGISTRYINDEX, data->data_ref); free(data->data); free(data); } luv-1.9.1-0/src/lreq.h000066400000000000000000000024601274770366500144130ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef LUV_LREQ_H #define LUV_LREQ_H #include "luv.h" typedef struct { int req_ref; /* ref for uv_req_t's userdata */ int callback_ref; /* ref for callback */ int data_ref; /* ref for write data */ void* data; /* extra data */ } luv_req_t; /* Used in the top of a setup function to check the arg and ref the callback to an integer. */ static int luv_check_continuation(lua_State* L, int index); /* setup a luv_req_t. The userdata is assumed to be at the top of the stack. */ static luv_req_t* luv_setup_req(lua_State* L, int ref); static void luv_fulfill_req(lua_State* L, luv_req_t* data, int nargs); static void luv_cleanup_req(lua_State* L, luv_req_t* data); #endif luv-1.9.1-0/src/lthreadpool.h000066400000000000000000000025071274770366500157670ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef LUV_LTHREADPOOL_H #define LUV_LTHREADPOOL_H #include "luv.h" #define LUV_THREAD_MAXNUM_ARG 9 typedef struct { /* only support LUA_TNIL, LUA_TBOOLEAN, LUA_TLIGHTUSERDATA, LUA_TNUMBER, LUA_TSTRING*/ int type; union { lua_Number num; int boolean; void* userdata; struct { const char* base; size_t len; } str; } val; } luv_val_t; typedef struct { int argc; luv_val_t argv[LUV_THREAD_MAXNUM_ARG]; } luv_thread_arg_t; static int luv_thread_arg_set(lua_State* L, luv_thread_arg_t* args, int idx, int top, int flag); static int luv_thread_arg_push(lua_State* L, const luv_thread_arg_t* args); static void luv_thread_arg_clear(luv_thread_arg_t* args); #endif //LUV_LTHREADPOOL_H luv-1.9.1-0/src/luv.c000066400000000000000000000335761274770366500142650ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "luv.h" #include "util.c" #include "lhandle.c" #include "lreq.c" #include "loop.c" #include "req.c" #include "handle.c" #include "timer.c" #include "prepare.c" #include "check.c" #include "idle.c" #include "async.c" #include "poll.c" #include "signal.c" #include "process.c" #include "stream.c" #include "tcp.c" #include "pipe.c" #include "tty.c" #include "udp.c" #include "fs_event.c" #include "fs_poll.c" #include "fs.c" #include "dns.c" #include "thread.c" #include "work.c" #include "misc.c" #include "constants.c" static const luaL_Reg luv_functions[] = { // loop.c {"loop_close", luv_loop_close}, {"run", luv_run}, {"loop_alive", luv_loop_alive}, {"stop", luv_stop}, {"backend_fd", luv_backend_fd}, {"backend_timeout", luv_backend_timeout}, {"now", luv_now}, {"update_time", luv_update_time}, {"walk", luv_walk}, // req.c {"cancel", luv_cancel}, // handle.c {"is_active", luv_is_active}, {"is_closing", luv_is_closing}, {"close", luv_close}, {"ref", luv_ref}, {"unref", luv_unref}, {"has_ref", luv_has_ref}, {"send_buffer_size", luv_send_buffer_size}, {"recv_buffer_size", luv_recv_buffer_size}, {"fileno", luv_fileno}, // timer.c {"new_timer", luv_new_timer}, {"timer_start", luv_timer_start}, {"timer_stop", luv_timer_stop}, {"timer_again", luv_timer_again}, {"timer_set_repeat", luv_timer_set_repeat}, {"timer_get_repeat", luv_timer_get_repeat}, // prepare.c {"new_prepare", luv_new_prepare}, {"prepare_start", luv_prepare_start}, {"prepare_stop", luv_prepare_stop}, // check.c {"new_check", luv_new_check}, {"check_start", luv_check_start}, {"check_stop", luv_check_stop}, // idle.c {"new_idle", luv_new_idle}, {"idle_start", luv_idle_start}, {"idle_stop", luv_idle_stop}, // async.c {"new_async", luv_new_async}, {"async_send", luv_async_send}, // poll.c {"new_poll", luv_new_poll}, {"new_socket_poll", luv_new_socket_poll}, {"poll_start", luv_poll_start}, {"poll_stop", luv_poll_stop}, // signal.c {"new_signal", luv_new_signal}, {"signal_start", luv_signal_start}, {"signal_stop", luv_signal_stop}, // process.c {"disable_stdio_inheritance", luv_disable_stdio_inheritance}, {"spawn", luv_spawn}, {"process_kill", luv_process_kill}, {"kill", luv_kill}, // stream.c {"shutdown", luv_shutdown}, {"listen", luv_listen}, {"accept", luv_accept}, {"read_start", luv_read_start}, {"read_stop", luv_read_stop}, {"write", luv_write}, {"write2", luv_write2}, {"try_write", luv_try_write}, {"is_readable", luv_is_readable}, {"is_writable", luv_is_writable}, {"stream_set_blocking", luv_stream_set_blocking}, // tcp.c {"new_tcp", luv_new_tcp}, {"tcp_open", luv_tcp_open}, {"tcp_nodelay", luv_tcp_nodelay}, {"tcp_keepalive", luv_tcp_keepalive}, {"tcp_simultaneous_accepts", luv_tcp_simultaneous_accepts}, {"tcp_bind", luv_tcp_bind}, {"tcp_getpeername", luv_tcp_getpeername}, {"tcp_getsockname", luv_tcp_getsockname}, {"tcp_connect", luv_tcp_connect}, {"tcp_write_queue_size", luv_write_queue_size}, // pipe.c {"new_pipe", luv_new_pipe}, {"pipe_open", luv_pipe_open}, {"pipe_bind", luv_pipe_bind}, {"pipe_connect", luv_pipe_connect}, {"pipe_getsockname", luv_pipe_getsockname}, {"pipe_getpeername", luv_pipe_getpeername}, {"pipe_pending_instances", luv_pipe_pending_instances}, {"pipe_pending_count", luv_pipe_pending_count}, {"pipe_pending_type", luv_pipe_pending_type}, // tty.c {"new_tty", luv_new_tty}, {"tty_set_mode", luv_tty_set_mode}, {"tty_reset_mode", luv_tty_reset_mode}, {"tty_get_winsize", luv_tty_get_winsize}, // udp.c {"new_udp", luv_new_udp}, {"udp_open", luv_udp_open}, {"udp_bind", luv_udp_bind}, {"udp_getsockname", luv_udp_getsockname}, {"udp_set_membership", luv_udp_set_membership}, {"udp_set_multicast_loop", luv_udp_set_multicast_loop}, {"udp_set_multicast_ttl", luv_udp_set_multicast_ttl}, {"udp_set_multicast_interface", luv_udp_set_multicast_interface}, {"udp_set_broadcast", luv_udp_set_broadcast}, {"udp_set_ttl", luv_udp_set_ttl}, {"udp_send", luv_udp_send}, {"udp_try_send", luv_udp_try_send}, {"udp_recv_start", luv_udp_recv_start}, {"udp_recv_stop", luv_udp_recv_stop}, // fs_event.c {"new_fs_event", luv_new_fs_event}, {"fs_event_start", luv_fs_event_start}, {"fs_event_stop", luv_fs_event_stop}, {"fs_event_getpath", luv_fs_event_getpath}, // fs_poll.c {"new_fs_poll", luv_new_fs_poll}, {"fs_poll_start", luv_fs_poll_start}, {"fs_poll_stop", luv_fs_poll_stop}, {"fs_poll_getpath", luv_fs_poll_getpath}, // fs.c {"fs_close", luv_fs_close}, {"fs_open", luv_fs_open}, {"fs_read", luv_fs_read}, {"fs_unlink", luv_fs_unlink}, {"fs_write", luv_fs_write}, {"fs_mkdir", luv_fs_mkdir}, {"fs_mkdtemp", luv_fs_mkdtemp}, {"fs_rmdir", luv_fs_rmdir}, {"fs_scandir", luv_fs_scandir}, {"fs_scandir_next", luv_fs_scandir_next}, {"fs_stat", luv_fs_stat}, {"fs_fstat", luv_fs_fstat}, {"fs_lstat", luv_fs_lstat}, {"fs_rename", luv_fs_rename}, {"fs_fsync", luv_fs_fsync}, {"fs_fdatasync", luv_fs_fdatasync}, {"fs_ftruncate", luv_fs_ftruncate}, {"fs_sendfile", luv_fs_sendfile}, {"fs_access", luv_fs_access}, {"fs_chmod", luv_fs_chmod}, {"fs_fchmod", luv_fs_fchmod}, {"fs_utime", luv_fs_utime}, {"fs_futime", luv_fs_futime}, {"fs_link", luv_fs_link}, {"fs_symlink", luv_fs_symlink}, {"fs_readlink", luv_fs_readlink}, {"fs_realpath", luv_fs_realpath}, {"fs_chown", luv_fs_chown}, {"fs_fchown", luv_fs_fchown}, // dns.c {"getaddrinfo", luv_getaddrinfo}, {"getnameinfo", luv_getnameinfo}, // misc.c {"chdir", luv_chdir}, {"os_homedir", luv_os_homedir}, {"os_tmpdir", luv_os_tmpdir}, {"os_get_passwd", luv_os_get_passwd}, {"cpu_info", luv_cpu_info}, {"cwd", luv_cwd}, {"exepath", luv_exepath}, {"get_process_title", luv_get_process_title}, {"get_total_memory", luv_get_total_memory}, {"get_free_memory", luv_get_free_memory}, {"getpid", luv_getpid}, #ifndef _WIN32 {"getuid", luv_getuid}, {"setuid", luv_setuid}, {"getgid", luv_getgid}, {"setgid", luv_setgid}, #endif {"getrusage", luv_getrusage}, {"guess_handle", luv_guess_handle}, {"hrtime", luv_hrtime}, {"interface_addresses", luv_interface_addresses}, {"loadavg", luv_loadavg}, {"resident_set_memory", luv_resident_set_memory}, {"set_process_title", luv_set_process_title}, {"uptime", luv_uptime}, {"version", luv_version}, {"version_string", luv_version_string}, #ifndef _WIN32 {"print_all_handles", luv_print_all_handles}, {"print_active_handles", luv_print_active_handles}, #endif // thread.c {"new_thread", luv_new_thread}, {"thread_equal", luv_thread_equal}, {"thread_self", luv_thread_self}, {"thread_join", luv_thread_join}, {"sleep", luv_thread_sleep}, // work.c {"new_work", luv_new_work}, {"queue_work", luv_queue_work}, {NULL, NULL} }; static const luaL_Reg luv_handle_methods[] = { // handle.c {"is_active", luv_is_active}, {"is_closing", luv_is_closing}, {"close", luv_close}, {"ref", luv_ref}, {"unref", luv_unref}, {"has_ref", luv_has_ref}, {"send_buffer_size", luv_send_buffer_size}, {"recv_buffer_size", luv_recv_buffer_size}, {"fileno", luv_fileno}, {NULL, NULL} }; static const luaL_Reg luv_async_methods[] = { {"send", luv_async_send}, {NULL, NULL} }; static const luaL_Reg luv_check_methods[] = { {"start", luv_check_start}, {"stop", luv_check_stop}, {NULL, NULL} }; static const luaL_Reg luv_fs_event_methods[] = { {"start", luv_fs_event_start}, {"stop", luv_fs_event_stop}, {"getpath", luv_fs_event_getpath}, {NULL, NULL} }; static const luaL_Reg luv_fs_poll_methods[] = { {"start", luv_fs_poll_start}, {"stop", luv_fs_poll_stop}, {"getpath", luv_fs_poll_getpath}, {NULL, NULL} }; static const luaL_Reg luv_idle_methods[] = { {"start", luv_idle_start}, {"stop", luv_idle_stop}, {NULL, NULL} }; static const luaL_Reg luv_stream_methods[] = { {"shutdown", luv_shutdown}, {"listen", luv_listen}, {"accept", luv_accept}, {"read_start", luv_read_start}, {"read_stop", luv_read_stop}, {"write", luv_write}, {"write2", luv_write2}, {"try_write", luv_try_write}, {"is_readable", luv_is_readable}, {"is_writable", luv_is_writable}, {"set_blocking", luv_stream_set_blocking}, {NULL, NULL} }; static const luaL_Reg luv_pipe_methods[] = { {"open", luv_pipe_open}, {"bind", luv_pipe_bind}, {"connect", luv_pipe_connect}, {"getsockname", luv_pipe_getsockname}, {"getpeername", luv_pipe_getpeername}, {"pending_instances", luv_pipe_pending_instances}, {"pending_count", luv_pipe_pending_count}, {"pending_type", luv_pipe_pending_type}, {NULL, NULL} }; static const luaL_Reg luv_poll_methods[] = { {"start", luv_poll_start}, {"stop", luv_poll_stop}, {NULL, NULL} }; static const luaL_Reg luv_prepare_methods[] = { {"start", luv_prepare_start}, {"stop", luv_prepare_stop}, {NULL, NULL} }; static const luaL_Reg luv_process_methods[] = { {"kill", luv_process_kill}, {NULL, NULL} }; static const luaL_Reg luv_tcp_methods[] = { {"open", luv_tcp_open}, {"nodelay", luv_tcp_nodelay}, {"keepalive", luv_tcp_keepalive}, {"simultaneous_accepts", luv_tcp_simultaneous_accepts}, {"bind", luv_tcp_bind}, {"getpeername", luv_tcp_getpeername}, {"getsockname", luv_tcp_getsockname}, {"connect", luv_tcp_connect}, {"write_queue_size", luv_write_queue_size}, {NULL, NULL} }; static const luaL_Reg luv_timer_methods[] = { {"start", luv_timer_start}, {"stop", luv_timer_stop}, {"again", luv_timer_again}, {"set_repeat", luv_timer_set_repeat}, {"get_repeat", luv_timer_get_repeat}, {NULL, NULL} }; static const luaL_Reg luv_tty_methods[] = { {"set_mode", luv_tty_set_mode}, {"get_winsize", luv_tty_get_winsize}, {NULL, NULL} }; static const luaL_Reg luv_udp_methods[] = { {"open", luv_udp_open}, {"bind", luv_udp_bind}, {"bindgetsockname", luv_udp_getsockname}, {"set_membership", luv_udp_set_membership}, {"set_multicast_loop", luv_udp_set_multicast_loop}, {"set_multicast_ttl", luv_udp_set_multicast_ttl}, {"set_multicast_interface", luv_udp_set_multicast_interface}, {"set_broadcast", luv_udp_set_broadcast}, {"set_ttl", luv_udp_set_ttl}, {"send", luv_udp_send}, {"try_send", luv_udp_try_send}, {"recv_start", luv_udp_recv_start}, {"recv_stop", luv_udp_recv_stop}, {NULL, NULL} }; static const luaL_Reg luv_signal_methods[] = { {"start", luv_signal_start}, {"stop", luv_signal_stop}, {NULL, NULL} }; static void luv_handle_init(lua_State* L) { lua_newtable(L); #define XX(uc, lc) \ luaL_newmetatable (L, "uv_"#lc); \ lua_pushcfunction(L, luv_handle_tostring); \ lua_setfield(L, -2, "__tostring"); \ lua_pushcfunction(L, luv_handle_gc); \ lua_setfield(L, -2, "__gc"); \ luaL_newlib(L, luv_##lc##_methods); \ luaL_setfuncs(L, luv_handle_methods, 0); \ lua_setfield(L, -2, "__index"); \ lua_pushboolean(L, 1); \ lua_rawset(L, -3); UV_HANDLE_TYPE_MAP(XX) #undef XX lua_setfield(L, LUA_REGISTRYINDEX, "uv_handle"); lua_newtable(L); luaL_getmetatable(L, "uv_pipe"); lua_getfield(L, -1, "__index"); luaL_setfuncs(L, luv_stream_methods, 0); lua_pop(L, 1); lua_pushboolean(L, 1); lua_rawset(L, -3); luaL_getmetatable(L, "uv_tcp"); lua_getfield(L, -1, "__index"); luaL_setfuncs(L, luv_stream_methods, 0); lua_pop(L, 1); lua_pushboolean(L, 1); lua_rawset(L, -3); luaL_getmetatable(L, "uv_tty"); lua_getfield(L, -1, "__index"); luaL_setfuncs(L, luv_stream_methods, 0); lua_pop(L, 1); lua_pushboolean(L, 1); lua_rawset(L, -3); lua_setfield(L, LUA_REGISTRYINDEX, "uv_stream"); } LUALIB_API lua_State* luv_state(uv_loop_t* loop) { return (lua_State*)loop->data; } // TODO: find out if storing this somehow in an upvalue is faster LUALIB_API uv_loop_t* luv_loop(lua_State* L) { uv_loop_t* loop; lua_pushstring(L, "uv_loop"); lua_rawget(L, LUA_REGISTRYINDEX); loop = (uv_loop_t*)lua_touserdata(L, -1); lua_pop(L, 1); return loop; } static void walk_cb(uv_handle_t *handle, void *arg) { (void)arg; if (!uv_is_closing(handle)) { uv_close(handle, luv_close_cb); } } static int loop_gc(lua_State *L) { uv_loop_t* loop = luv_loop(L); // Call uv_close on every active handle uv_walk(loop, walk_cb, NULL); // Run the event loop until all handles are successfully closed while (uv_loop_close(loop)) { uv_run(loop, UV_RUN_DEFAULT); } return 0; } LUALIB_API int luaopen_luv (lua_State *L) { uv_loop_t* loop; int ret; // Setup the uv_loop meta table for a proper __gc luaL_newmetatable(L, "uv_loop.meta"); lua_pushstring(L, "__gc"); lua_pushcfunction(L, loop_gc); lua_settable(L, -3); loop = (uv_loop_t*)lua_newuserdata(L, sizeof(*loop)); ret = uv_loop_init(loop); if (ret < 0) { return luaL_error(L, "%s: %s\n", uv_err_name(ret), uv_strerror(ret)); } // setup the metatable for __gc luaL_getmetatable(L, "uv_loop.meta"); lua_setmetatable(L, -2); // Tell the state how to find the loop. lua_pushstring(L, "uv_loop"); lua_insert(L, -2); lua_rawset(L, LUA_REGISTRYINDEX); lua_pop(L, 1); // Tell the loop how to find the state. loop->data = L; luv_req_init(L); luv_handle_init(L); luv_thread_init(L); luv_work_init(L); luaL_newlib(L, luv_functions); luv_constants(L); lua_setfield(L, -2, "constants"); return 1; } luv-1.9.1-0/src/luv.h000066400000000000000000000070411274770366500142560ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef LUV_H #define LUV_H #include #include #include #include "uv.h" #include #include #include #if defined(_WIN32) # include # include # include # ifndef __MINGW32__ # define S_ISREG(x) (((x) & _S_IFMT) == _S_IFREG) # define S_ISDIR(x) (((x) & _S_IFMT) == _S_IFDIR) # define S_ISFIFO(x) (((x) & _S_IFMT) == _S_IFIFO) # define S_ISCHR(x) (((x) & _S_IFMT) == _S_IFCHR) # define S_ISBLK(x) 0 # endif # define S_ISLNK(x) (((x) & S_IFLNK) == S_IFLNK) # define S_ISSOCK(x) 0 #else # include #endif #ifndef PATH_MAX #define PATH_MAX (8096) #endif #ifndef MAX_TITLE_LENGTH #define MAX_TITLE_LENGTH (8192) #endif #if LUA_VERSION_NUM < 502 # define lua_rawlen lua_objlen /* lua_...uservalue: Something very different, but it should get the job done */ # define lua_getuservalue lua_getfenv # define lua_setuservalue lua_setfenv # define luaL_newlib(L,l) (lua_newtable(L), luaL_register(L,NULL,l)) # define luaL_setfuncs(L,l,n) (assert(n==0), luaL_register(L,NULL,l)) # define lua_resume(L,F,n) lua_resume(L,n) # define lua_pushglobaltable(L) lua_pushvalue(L, LUA_GLOBALSINDEX) #endif /* There is a 1-1 relation between a lua_State and a uv_loop_t These helpers will give you one if you have the other These are exposed for extensions built with luv This allows luv to be used in multithreaded applications. */ LUALIB_API lua_State* luv_state(uv_loop_t* loop); /* All libuv callbacks will lua_call directly from this root-per-thread state */ LUALIB_API uv_loop_t* luv_loop(lua_State* L); /* This is the main hook to load the library. This can be called multiple times in a process as long as you use a different lua_State and thread for each. */ LUALIB_API int luaopen_luv (lua_State *L); #include "util.h" #include "lhandle.h" #include "lreq.h" /* From stream.c */ static uv_stream_t* luv_check_stream(lua_State* L, int index); static void luv_alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf); static void luv_check_buf(lua_State *L, int idx, uv_buf_t *pbuf); static uv_buf_t* luv_prep_bufs(lua_State* L, int index, size_t *count); /* from tcp.c */ static void parse_sockaddr(lua_State* L, struct sockaddr_storage* address, int addrlen); static void luv_connect_cb(uv_connect_t* req, int status); /* From fs.c */ static void luv_push_stats_table(lua_State* L, const uv_stat_t* s); /* from constants.c */ static int luv_af_string_to_num(const char* string); static const char* luv_af_num_to_string(const int num); static int luv_sock_string_to_num(const char* string); static const char* luv_sock_num_to_string(const int num); static int luv_sig_string_to_num(const char* string); static const char* luv_sig_num_to_string(const int num); typedef lua_State* (*luv_acquire_vm)(); typedef void (*luv_release_vm)(lua_State* L); LUALIB_API void luv_set_thread_cb(luv_acquire_vm acquire, luv_release_vm release); #endif luv-1.9.1-0/src/misc.c000066400000000000000000000231211274770366500143730ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "luv.h" #ifdef _WIN32 #include #endif static int luv_guess_handle(lua_State* L) { uv_file file = luaL_checkinteger(L, 1); switch (uv_guess_handle(file)) { #define XX(uc, lc) case UV_##uc: lua_pushstring(L, #lc); break; UV_HANDLE_TYPE_MAP(XX) #undef XX case UV_FILE: lua_pushstring(L, "file"); break; default: return 0; } return 1; } static int luv_version(lua_State* L) { lua_pushinteger(L, uv_version()); return 1; } static int luv_version_string(lua_State* L) { lua_pushstring(L, uv_version_string()); return 1; } static int luv_get_process_title(lua_State* L) { char title[MAX_TITLE_LENGTH]; int ret = uv_get_process_title(title, MAX_TITLE_LENGTH); if (ret < 0) return luv_error(L, ret); lua_pushstring(L, title); return 1; } static int luv_set_process_title(lua_State* L) { const char* title = luaL_checkstring(L, 1); int ret = uv_set_process_title(title); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_resident_set_memory(lua_State* L) { size_t rss; int ret = uv_resident_set_memory(&rss); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, rss); return 1; } static int luv_uptime(lua_State* L) { double uptime; int ret = uv_uptime(&uptime); if (ret < 0) return luv_error(L, ret); lua_pushnumber(L, uptime); return 1; } static void luv_push_timeval_table(lua_State* L, const uv_timeval_t* t) { lua_createtable(L, 0, 2); lua_pushinteger(L, t->tv_sec); lua_setfield(L, -2, "sec"); lua_pushinteger(L, t->tv_usec); lua_setfield(L, -2, "usec"); } static int luv_getrusage(lua_State* L) { uv_rusage_t rusage; int ret = uv_getrusage(&rusage); if (ret < 0) return luv_error(L, ret); lua_createtable(L, 0, 16); // user CPU time used luv_push_timeval_table(L, &rusage.ru_utime); lua_setfield(L, -2, "utime"); // system CPU time used luv_push_timeval_table(L, &rusage.ru_stime); lua_setfield(L, -2, "stime"); // maximum resident set size lua_pushinteger(L, rusage.ru_maxrss); lua_setfield(L, -2, "maxrss"); // integral shared memory size lua_pushinteger(L, rusage.ru_ixrss); lua_setfield(L, -2, "ixrss"); // integral unshared data size lua_pushinteger(L, rusage.ru_idrss); lua_setfield(L, -2, "idrss"); // integral unshared stack size lua_pushinteger(L, rusage.ru_isrss); lua_setfield(L, -2, "isrss"); // page reclaims (soft page faults) lua_pushinteger(L, rusage.ru_minflt); lua_setfield(L, -2, "minflt"); // page faults (hard page faults) lua_pushinteger(L, rusage.ru_majflt); lua_setfield(L, -2, "majflt"); // swaps lua_pushinteger(L, rusage.ru_nswap); lua_setfield(L, -2, "nswap"); // block input operations lua_pushinteger(L, rusage.ru_inblock); lua_setfield(L, -2, "inblock"); // block output operations lua_pushinteger(L, rusage.ru_oublock); lua_setfield(L, -2, "oublock"); // IPC messages sent lua_pushinteger(L, rusage.ru_msgsnd); lua_setfield(L, -2, "msgsnd"); // IPC messages received lua_pushinteger(L, rusage.ru_msgrcv); lua_setfield(L, -2, "msgrcv"); // signals received lua_pushinteger(L, rusage.ru_nsignals); lua_setfield(L, -2, "nsignals"); // voluntary context switches lua_pushinteger(L, rusage.ru_nvcsw); lua_setfield(L, -2, "nvcsw"); // involuntary context switches lua_pushinteger(L, rusage.ru_nivcsw); lua_setfield(L, -2, "nivcsw"); return 1; } static int luv_cpu_info(lua_State* L) { uv_cpu_info_t* cpu_infos; int count, i; int ret = uv_cpu_info(&cpu_infos, &count); if (ret < 0) return luv_error(L, ret); lua_newtable(L); for (i = 0; i < count; i++) { lua_newtable(L); lua_pushstring(L, cpu_infos[i].model); lua_setfield(L, -2, "model"); lua_pushnumber(L, cpu_infos[i].speed); lua_setfield(L, -2, "speed"); lua_newtable(L); lua_pushnumber(L, cpu_infos[i].cpu_times.user); lua_setfield(L, -2, "user"); lua_pushnumber(L, cpu_infos[i].cpu_times.nice); lua_setfield(L, -2, "nice"); lua_pushnumber(L, cpu_infos[i].cpu_times.sys); lua_setfield(L, -2, "sys"); lua_pushnumber(L, cpu_infos[i].cpu_times.idle); lua_setfield(L, -2, "idle"); lua_pushnumber(L, cpu_infos[i].cpu_times.irq); lua_setfield(L, -2, "irq"); lua_setfield(L, -2, "times"); lua_rawseti(L, -2, i + 1); } uv_free_cpu_info(cpu_infos, count); return 1; } static int luv_interface_addresses(lua_State* L) { uv_interface_address_t* interfaces; int count, i; char ip[INET6_ADDRSTRLEN]; char netmask[INET6_ADDRSTRLEN]; uv_interface_addresses(&interfaces, &count); lua_newtable(L); for (i = 0; i < count; i++) { lua_getfield(L, -1, interfaces[i].name); if (!lua_istable(L, -1)) { lua_pop(L, 1); lua_newtable(L); lua_pushvalue(L, -1); lua_setfield(L, -3, interfaces[i].name); } lua_newtable(L); lua_pushboolean(L, interfaces[i].is_internal); lua_setfield(L, -2, "internal"); lua_pushlstring(L, interfaces[i].phys_addr, sizeof(interfaces[i].phys_addr)); lua_setfield(L, -2, "mac"); if (interfaces[i].address.address4.sin_family == AF_INET) { uv_ip4_name(&interfaces[i].address.address4, ip, sizeof(ip)); uv_ip4_name(&interfaces[i].netmask.netmask4, netmask, sizeof(netmask)); } else if (interfaces[i].address.address4.sin_family == AF_INET6) { uv_ip6_name(&interfaces[i].address.address6, ip, sizeof(ip)); uv_ip6_name(&interfaces[i].netmask.netmask6, netmask, sizeof(netmask)); } else { strncpy(ip, "", INET6_ADDRSTRLEN); strncpy(netmask, "", INET6_ADDRSTRLEN); } lua_pushstring(L, ip); lua_setfield(L, -2, "ip"); lua_pushstring(L, netmask); lua_setfield(L, -2, "netmask"); lua_pushstring(L, luv_af_num_to_string(interfaces[i].address.address4.sin_family)); lua_setfield(L, -2, "family"); lua_rawseti(L, -2, lua_rawlen (L, -2) + 1); lua_pop(L, 1); } uv_free_interface_addresses(interfaces, count); return 1; } static int luv_loadavg(lua_State* L) { double avg[3]; uv_loadavg(avg); lua_pushnumber(L, avg[0]); lua_pushnumber(L, avg[1]); lua_pushnumber(L, avg[2]); return 3; } static int luv_exepath(lua_State* L) { size_t size = 2*PATH_MAX; char exe_path[2*PATH_MAX]; int ret = uv_exepath(exe_path, &size); if (ret < 0) return luv_error(L, ret); lua_pushlstring(L, exe_path, size); return 1; } static int luv_cwd(lua_State* L) { size_t size = 2*PATH_MAX; char path[2*PATH_MAX]; int ret = uv_cwd(path, &size); if (ret < 0) return luv_error(L, ret); lua_pushlstring(L, path, size); return 1; } static int luv_chdir(lua_State* L) { int ret = uv_chdir(luaL_checkstring(L, 1)); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_os_tmpdir(lua_State* L) { size_t size = 2*PATH_MAX; char tmpdir[2*PATH_MAX]; int ret = uv_os_tmpdir(tmpdir, &size); if (ret < 0) return luv_error(L, ret); lua_pushlstring(L, tmpdir, size); return 1; } static int luv_os_homedir(lua_State* L) { size_t size = 2*PATH_MAX; char homedir[2*PATH_MAX]; int ret = uv_os_homedir(homedir, &size); if (ret < 0) return luv_error(L, ret); lua_pushlstring(L, homedir, size); return 1; } static int luv_os_get_passwd(lua_State* L) { uv_passwd_t pwd; int ret = uv_os_get_passwd(&pwd); if (ret < 0) return luv_error(L, ret); lua_newtable(L); if (pwd.username) { lua_pushstring(L, pwd.username); lua_setfield(L, -2, "username"); } if (pwd.uid >= 0) { lua_pushinteger(L, pwd.uid); lua_setfield(L, -2, "uid"); } if (pwd.gid >= 0) { lua_pushinteger(L, pwd.gid); lua_setfield(L, -2, "gid"); } if (pwd.shell) { lua_pushstring(L, pwd.shell); lua_setfield(L, -2, "shell"); } if (pwd.homedir) { lua_pushstring(L, pwd.homedir); lua_setfield(L, -2, "homedir"); } uv_os_free_passwd(&pwd); return 1; } static int luv_get_total_memory(lua_State* L) { lua_pushnumber(L, uv_get_total_memory()); return 1; } static int luv_get_free_memory(lua_State* L) { lua_pushnumber(L, uv_get_free_memory()); return 1; } static int luv_hrtime(lua_State* L) { lua_pushnumber(L, uv_hrtime()); return 1; } static int luv_getpid(lua_State* L){ int pid = getpid(); lua_pushinteger(L, pid); return 1; } #ifndef _WIN32 static int luv_getuid(lua_State* L){ int uid = getuid(); lua_pushinteger(L, uid); return 1; } static int luv_getgid(lua_State* L){ int gid = getgid(); lua_pushinteger(L, gid); return 1; } static int luv_setuid(lua_State* L){ int uid = luaL_checkinteger(L, 1); int r = setuid(uid); if (-1 == r) { luaL_error(L, "Error setting UID"); } return 0; } static int luv_setgid(lua_State* L){ int gid = luaL_checkinteger(L, 1); int r = setgid(gid); if (-1 == r) { luaL_error(L, "Error setting GID"); } return 0; } #ifndef _WIN32 static int luv_print_all_handles(lua_State* L){ uv_print_all_handles(luv_loop(L), stderr); return 0; } static int luv_print_active_handles(lua_State* L){ uv_print_active_handles(luv_loop(L), stderr); return 0; } #endif #endif luv-1.9.1-0/src/pipe.c000066400000000000000000000065301274770366500144020ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "luv.h" static uv_pipe_t* luv_check_pipe(lua_State* L, int index) { uv_pipe_t* handle = (uv_pipe_t*)luv_checkudata(L, index, "uv_pipe"); luaL_argcheck(L, handle->type == UV_NAMED_PIPE && handle->data, index, "Expected uv_pipe_t"); return handle; } static int luv_new_pipe(lua_State* L) { uv_pipe_t* handle; int ipc, ret; luaL_checktype(L, 1, LUA_TBOOLEAN); ipc = lua_toboolean(L, 1); handle = (uv_pipe_t*)luv_newuserdata(L, sizeof(*handle)); ret = uv_pipe_init(luv_loop(L), handle, ipc); if (ret < 0) { lua_pop(L, 1); return luv_error(L, ret); } handle->data = luv_setup_handle(L); return 1; } static int luv_pipe_open(lua_State* L) { uv_pipe_t* handle = luv_check_pipe(L, 1); uv_file file = luaL_checkinteger(L, 2); int ret = uv_pipe_open(handle, file); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_pipe_bind(lua_State* L) { uv_pipe_t* handle = luv_check_pipe(L, 1); const char* name = luaL_checkstring(L, 2); int ret = uv_pipe_bind(handle, name); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_pipe_connect(lua_State* L) { uv_pipe_t* handle = luv_check_pipe(L, 1); const char* name = luaL_checkstring(L, 2); int ref = luv_check_continuation(L, 3); uv_connect_t* req = (uv_connect_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); uv_pipe_connect(req, handle, name, luv_connect_cb); return 1; } static int luv_pipe_getsockname(lua_State* L) { uv_pipe_t* handle = luv_check_pipe(L, 1); size_t len = 2*PATH_MAX; char buf[2*PATH_MAX]; int ret = uv_pipe_getsockname(handle, buf, &len); if (ret < 0) return luv_error(L, ret); lua_pushlstring(L, buf, len); return 1; } static int luv_pipe_getpeername(lua_State* L) { uv_pipe_t* handle = luv_check_pipe(L, 1); size_t len = 2*PATH_MAX; char buf[2*PATH_MAX]; int ret = uv_pipe_getpeername(handle, buf, &len); if (ret < 0) return luv_error(L, ret); lua_pushlstring(L, buf, len); return 1; } static int luv_pipe_pending_instances(lua_State* L) { uv_pipe_t* handle = luv_check_pipe(L, 1); int count = luaL_checkinteger(L, 2); uv_pipe_pending_instances(handle, count); return 0; } static int luv_pipe_pending_count(lua_State* L) { uv_pipe_t* handle = luv_check_pipe(L, 1); lua_pushinteger(L, uv_pipe_pending_count(handle)); return 1; } static int luv_pipe_pending_type(lua_State* L) { uv_pipe_t* handle = luv_check_pipe(L, 1); uv_handle_type type = uv_pipe_pending_type(handle); const char* type_name; switch (type) { #define XX(uc, lc) \ case UV_##uc: type_name = #lc; break; UV_HANDLE_TYPE_MAP(XX) #undef XX default: return 0; } lua_pushstring(L, type_name); return 1; } luv-1.9.1-0/src/poll.c000066400000000000000000000067421274770366500144200ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "luv.h" static uv_poll_t* luv_check_poll(lua_State* L, int index) { uv_poll_t* handle = (uv_poll_t*)luv_checkudata(L, index, "uv_poll"); luaL_argcheck(L, handle->type == UV_POLL && handle->data, index, "Expected uv_poll_t"); return handle; } static int luv_new_poll(lua_State* L) { int fd = luaL_checkinteger(L, 1); uv_poll_t* handle = (uv_poll_t*)luv_newuserdata(L, sizeof(*handle)); int ret = uv_poll_init(luv_loop(L), handle, fd); if (ret < 0) { lua_pop(L, 1); return luv_error(L, ret); } handle->data = luv_setup_handle(L); return 1; } static int luv_new_socket_poll(lua_State* L) { int fd = luaL_checkinteger(L, 1); uv_poll_t* handle = (uv_poll_t*)luv_newuserdata(L, sizeof(*handle)); int ret = uv_poll_init_socket(luv_loop(L), handle, fd); if (ret < 0) { lua_pop(L, 1); return luv_error(L, ret); } handle->data = luv_setup_handle(L); return 1; } // These are the same order as uv_run_mode which also starts at 0 static const char *const luv_pollevents[] = { "r", "w", "rw", "d", "rd", "wd", "rwd", NULL }; static void luv_poll_cb(uv_poll_t* handle, int status, int events) { lua_State* L = luv_state(handle->loop); luv_handle_t* data = (luv_handle_t*)handle->data; const char* evtstr; if (status < 0) { fprintf(stderr, "%s: %s\n", uv_err_name(status), uv_strerror(status)); lua_pushstring(L, uv_err_name(status)); } else { lua_pushnil(L); } switch (events) { case UV_READABLE: evtstr = "r"; break; case UV_WRITABLE: evtstr = "w"; break; case UV_READABLE|UV_WRITABLE: evtstr = "rw"; break; case UV_DISCONNECT: evtstr = "d"; break; case UV_READABLE|UV_DISCONNECT: evtstr = "rd"; break; case UV_WRITABLE|UV_DISCONNECT: evtstr = "wd"; break; case UV_READABLE|UV_WRITABLE|UV_DISCONNECT: evtstr = "rwd"; break; default: evtstr = ""; break; } lua_pushstring(L, evtstr); luv_call_callback(L, data, LUV_POLL, 2); } static int luv_poll_start(lua_State* L) { uv_poll_t* handle = luv_check_poll(L, 1); int events, ret; switch (luaL_checkoption(L, 2, "rw", luv_pollevents)) { case 0: events = UV_READABLE; break; case 1: events = UV_WRITABLE; break; case 2: events = UV_READABLE | UV_WRITABLE; break; case 3: events = UV_DISCONNECT; break; case 4: events = UV_READABLE|UV_DISCONNECT; break; case 5: events = UV_WRITABLE|UV_DISCONNECT; break; case 6: events = UV_READABLE|UV_WRITABLE|UV_DISCONNECT; break; default: events = 0; /* unreachable */ } luv_check_callback(L, (luv_handle_t*)handle->data, LUV_POLL, 3); ret = uv_poll_start(handle, events, luv_poll_cb); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_poll_stop(lua_State* L) { uv_poll_t* handle = luv_check_poll(L, 1); int ret = uv_poll_stop(handle); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } luv-1.9.1-0/src/prepare.c000066400000000000000000000036061274770366500151040ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "luv.h" static uv_prepare_t* luv_check_prepare(lua_State* L, int index) { uv_prepare_t* handle = (uv_prepare_t*)luv_checkudata(L, index, "uv_prepare"); luaL_argcheck(L, handle->type == UV_PREPARE && handle->data, index, "Expected uv_prepare_t"); return handle; } static int luv_new_prepare(lua_State* L) { uv_prepare_t* handle = (uv_prepare_t*)luv_newuserdata(L, sizeof(*handle)); int ret = uv_prepare_init(luv_loop(L), handle); if (ret < 0) { lua_pop(L, 1); return luv_error(L, ret); } handle->data = luv_setup_handle(L); return 1; } static void luv_prepare_cb(uv_prepare_t* handle) { lua_State* L = luv_state(handle->loop); luv_handle_t* data = (luv_handle_t*)handle->data; luv_call_callback(L, data, LUV_PREPARE, 0); } static int luv_prepare_start(lua_State* L) { uv_prepare_t* handle = luv_check_prepare(L, 1); int ret; luv_check_callback(L, (luv_handle_t*)handle->data, LUV_PREPARE, 2); ret = uv_prepare_start(handle, luv_prepare_cb); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_prepare_stop(lua_State* L) { uv_prepare_t* handle = luv_check_prepare(L, 1); int ret = uv_prepare_stop(handle); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } luv-1.9.1-0/src/process.c000066400000000000000000000174021274770366500151230ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "luv.h" static int luv_disable_stdio_inheritance(lua_State* L) { (void)L; uv_disable_stdio_inheritance(); return 0; } static uv_process_t* luv_check_process(lua_State* L, int index) { uv_process_t* handle = (uv_process_t*)luv_checkudata(L, index, "uv_process"); luaL_argcheck(L, handle->type == UV_PROCESS && handle->data, index, "Expected uv_process_t"); return handle; } static void exit_cb(uv_process_t* handle, int64_t exit_status, int term_signal) { lua_State* L = luv_state(handle->loop); luv_handle_t* data = (luv_handle_t*)handle->data; lua_pushinteger(L, exit_status); lua_pushinteger(L, term_signal); luv_call_callback(L, data, LUV_EXIT, 2); } static void luv_spawn_close_cb(uv_handle_t* handle) { lua_State *L = luv_state(handle->loop); luv_unref_handle(L, (luv_handle_t*)handle->data); } static void luv_clean_options(uv_process_options_t* options) { free(options->args); free(options->stdio); free(options->env); } static int luv_spawn(lua_State* L) { uv_process_t* handle; uv_process_options_t options; size_t i, len = 0; int ret; memset(&options, 0, sizeof(options)); options.exit_cb = exit_cb; options.file = luaL_checkstring(L, 1); options.flags = 0; // Make sure the 2nd argument is a table luaL_checktype(L, 2, LUA_TTABLE); // get the args list lua_getfield(L, 2, "args"); // +1 for inserted command at front if (lua_type(L, -1) == LUA_TTABLE) { len = 1 + lua_rawlen(L, -1); } else if (lua_type(L, -1) != LUA_TNIL) { luv_clean_options(&options); return luaL_argerror(L, 3, "args option must be table"); } else { len = 1; } // +1 for null terminator at end options.args = (char**)malloc((len + 1) * sizeof(*options.args)); if (!options.args) { luv_clean_options(&options); return luaL_error(L, "Problem allocating args"); } options.args[0] = (char*)options.file; for (i = 1; i < len; ++i) { lua_rawgeti(L, -1, i); options.args[i] = (char*)lua_tostring(L, -1); lua_pop(L, 1); } options.args[len] = NULL; lua_pop(L, 1); // get the stdio list lua_getfield(L, 2, "stdio"); if (lua_type(L, -1) == LUA_TTABLE) { options.stdio_count = len = lua_rawlen(L, -1); options.stdio = (uv_stdio_container_t*)malloc(len * sizeof(*options.stdio)); if (!options.stdio) { luv_clean_options(&options); return luaL_error(L, "Problem allocating stdio"); } for (i = 0; i < len; ++i) { lua_rawgeti(L, -1, i + 1); // integers are assumed to be file descripters if (lua_type(L, -1) == LUA_TNUMBER) { options.stdio[i].flags = UV_INHERIT_FD; options.stdio[i].data.fd = lua_tointeger(L, -1); } // userdata is assumed to be a uv_stream_t instance else if (lua_type(L, -1) == LUA_TUSERDATA) { uv_os_fd_t fd; uv_stream_t* stream = luv_check_stream(L, -1); int err = uv_fileno((uv_handle_t*)stream, &fd); if (err == UV_EINVAL || err == UV_EBADF) { // stdin (fd 0) is read-only, stdout and stderr (fds 1 & 2) are // write-only, and all fds > 2 are read-write int flags = UV_CREATE_PIPE; if (i == 0 || i > 2) flags |= UV_READABLE_PIPE; if (i != 0) flags |= UV_WRITABLE_PIPE; options.stdio[i].flags = (uv_stdio_flags)flags; } else { options.stdio[i].flags = UV_INHERIT_STREAM; } options.stdio[i].data.stream = stream; } else if (lua_type(L, -1) == LUA_TNIL) { options.stdio[i].flags = UV_IGNORE; } else { luv_clean_options(&options); return luaL_argerror(L, 2, "stdio table entries must be nil, uv_stream_t, or integer"); } lua_pop(L, 1); } } else if (lua_type(L, -1) != LUA_TNIL) { luv_clean_options(&options); return luaL_argerror(L, 2, "stdio option must be table"); } lua_pop(L, 1); // Get the env lua_getfield(L, 2, "env"); if (lua_type(L, -1) == LUA_TTABLE) { len = lua_rawlen(L, -1); options.env = (char**)malloc((len + 1) * sizeof(*options.env)); if (!options.env) { luv_clean_options(&options); return luaL_error(L, "Problem allocating env"); } for (i = 0; i < len; ++i) { lua_rawgeti(L, -1, i + 1); options.env[i] = (char*)lua_tostring(L, -1); lua_pop(L, 1); } options.env[len] = NULL; } else if (lua_type(L, -1) != LUA_TNIL) { luv_clean_options(&options); return luaL_argerror(L, 2, "env option must be table"); } lua_pop(L, 1); // Get the cwd lua_getfield(L, 2, "cwd"); if (lua_type(L, -1) == LUA_TSTRING) { options.cwd = (char*)lua_tostring(L, -1); } else if (lua_type(L, -1) != LUA_TNIL) { luv_clean_options(&options); return luaL_argerror(L, 2, "cwd option must be string"); } lua_pop(L, 1); // Check for uid lua_getfield(L, 2, "uid"); if (lua_type(L, -1) == LUA_TNUMBER) { options.uid = lua_tointeger(L, -1); options.flags |= UV_PROCESS_SETUID; } else if (lua_type(L, -1) != LUA_TNIL) { luv_clean_options(&options); return luaL_argerror(L, 2, "uid option must be number"); } lua_pop(L, 1); // Check for gid lua_getfield(L, 2, "gid"); if (lua_type(L, -1) == LUA_TNUMBER) { options.gid = lua_tointeger(L, -1); options.flags |= UV_PROCESS_SETGID; } else if (lua_type(L, -1) != LUA_TNIL) { luv_clean_options(&options); return luaL_argerror(L, 2, "gid option must be number"); } lua_pop(L, 1); // Check for the boolean flags lua_getfield(L, 2, "verbatim"); if (lua_toboolean(L, -1)) { options.flags |= UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS; } lua_pop(L, 1); lua_getfield(L, 2, "detached"); if (lua_toboolean(L, -1)) { options.flags |= UV_PROCESS_DETACHED; } lua_pop(L, 1); lua_getfield(L, 2, "hide"); if (lua_toboolean(L, -1)) { options.flags |= UV_PROCESS_WINDOWS_HIDE; } lua_pop(L, 1); handle = (uv_process_t*)luv_newuserdata(L, sizeof(*handle)); handle->type = UV_PROCESS; handle->data = luv_setup_handle(L); if (!lua_isnoneornil(L, 3)) { luv_check_callback(L, (luv_handle_t*)handle->data, LUV_EXIT, 3); } ret = uv_spawn(luv_loop(L), handle, &options); luv_clean_options(&options); if (ret < 0) { /* The async callback is required here because luajit GC may reclaim the * luv handle before libuv is done closing it down. */ uv_close((uv_handle_t*)handle, luv_spawn_close_cb); return luv_error(L, ret); } lua_pushinteger(L, handle->pid); return 2; } static int luv_parse_signal(lua_State* L, int slot) { if (lua_isnumber(L, slot)) { return lua_tonumber(L, slot); } if (lua_isstring(L, slot)) { return luv_sig_string_to_num(lua_tostring(L, slot)); } return SIGTERM; } static int luv_process_kill(lua_State* L) { uv_process_t* handle = luv_check_process(L, 1); int signum = luv_parse_signal(L, 2); int ret = uv_process_kill(handle, signum); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_kill(lua_State* L) { int pid = luaL_checkinteger(L, 1); int signum = luv_parse_signal(L, 2); int ret = uv_kill(pid, signum); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } luv-1.9.1-0/src/req.c000066400000000000000000000032261274770366500142330ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "luv.h" static uv_req_t* luv_check_req(lua_State* L, int index) { uv_req_t* req = (uv_req_t*)luaL_checkudata(L, index, "uv_req"); luaL_argcheck(L, req->data, index, "Expected uv_req_t"); return req; } static int luv_req_tostring(lua_State* L) { uv_req_t* req = (uv_req_t*)luaL_checkudata(L, 1, "uv_req"); switch (req->type) { #define XX(uc, lc) case UV_##uc: lua_pushfstring(L, "uv_"#lc"_t: %p", req); break; UV_REQ_TYPE_MAP(XX) #undef XX default: lua_pushfstring(L, "uv_req_t: %p", req); break; } return 1; } static void luv_req_init(lua_State* L) { luaL_newmetatable (L, "uv_req"); lua_pushcfunction(L, luv_req_tostring); lua_setfield(L, -2, "__tostring"); lua_pop(L, 1); } // Metamethod to allow storing anything in the userdata's environment static int luv_cancel(lua_State* L) { uv_req_t* req = (uv_req_t*)luv_check_req(L, 1); int ret = uv_cancel(req); if (ret < 0) return luv_error(L, ret); luv_cleanup_req(L, (luv_req_t*)req->data); req->data = NULL; lua_pushinteger(L, ret); return 1; } luv-1.9.1-0/src/schema.c000066400000000000000000000011741274770366500147040ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ luv-1.9.1-0/src/signal.c000066400000000000000000000044031274770366500147170ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "luv.h" static uv_signal_t* luv_check_signal(lua_State* L, int index) { uv_signal_t* handle = (uv_signal_t*)luv_checkudata(L, index, "uv_signal"); luaL_argcheck(L, handle->type == UV_SIGNAL && handle->data, index, "Expected uv_signal_t"); return handle; } static int luv_new_signal(lua_State* L) { uv_signal_t* handle = (uv_signal_t*)luv_newuserdata(L, sizeof(*handle)); int ret = uv_signal_init(luv_loop(L), handle); if (ret < 0) { lua_pop(L, 1); return luv_error(L, ret); } handle->data = luv_setup_handle(L); return 1; } static void luv_signal_cb(uv_signal_t* handle, int signum) { lua_State* L = luv_state(handle->loop); luv_handle_t* data = (luv_handle_t*)handle->data; lua_pushstring(L, luv_sig_num_to_string(signum)); luv_call_callback(L, data, LUV_SIGNAL, 1); } static int luv_signal_start(lua_State* L) { uv_signal_t* handle = luv_check_signal(L, 1); int signum, ret; if (lua_isnumber(L, 2)) { signum = lua_tointeger(L, 2); } else if (lua_isstring(L, 2)) { signum = luv_sig_string_to_num(luaL_checkstring(L, 2)); luaL_argcheck(L, signum, 2, "Invalid Signal name"); } else { return luaL_argerror(L, 2, "Missing Signal name"); } if (!lua_isnoneornil(L, 3)) { luv_check_callback(L, (luv_handle_t*)handle->data, LUV_SIGNAL, 3); } ret = uv_signal_start(handle, luv_signal_cb, signum); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_signal_stop(lua_State* L) { uv_signal_t* handle = luv_check_signal(L, 1); int ret = uv_signal_stop(handle); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } luv-1.9.1-0/src/stream.c000066400000000000000000000167401274770366500147440ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "luv.h" static void luv_check_buf(lua_State *L, int idx, uv_buf_t *pbuf) { size_t len; pbuf->base = (char*)luaL_checklstring(L, idx, &len); pbuf->len = len; } static uv_stream_t* luv_check_stream(lua_State* L, int index) { int isStream; uv_stream_t* handle; if (!(handle = *(uv_stream_t**) lua_touserdata(L, index))) { goto fail; } if (!handle->data) { goto fail; } lua_getfield(L, LUA_REGISTRYINDEX, "uv_stream"); lua_getmetatable(L, index < 0 ? index - 1 : index); lua_rawget(L, -2); isStream = lua_toboolean(L, -1); lua_pop(L, 2); if (isStream) { return handle; } fail: luaL_argerror(L, index, "Expected uv_stream userdata"); return NULL; } static void luv_shutdown_cb(uv_shutdown_t* req, int status) { lua_State* L = luv_state(req->handle->loop); luv_status(L, status); luv_fulfill_req(L, (luv_req_t*)req->data, 1); luv_cleanup_req(L, (luv_req_t*)req->data); req->data = NULL; } static int luv_shutdown(lua_State* L) { uv_stream_t* handle = luv_check_stream(L, 1); int ref = luv_check_continuation(L, 2); uv_shutdown_t* req = (uv_shutdown_t*)lua_newuserdata(L, sizeof(*req)); int ret; req->data = luv_setup_req(L, ref); ret = uv_shutdown(req, handle, luv_shutdown_cb); if (ret < 0) { luv_cleanup_req(L, (luv_req_t*)req->data); lua_pop(L, 1); return luv_error(L, ret); } return 1; } static void luv_connection_cb(uv_stream_t* handle, int status) { lua_State* L = luv_state(handle->loop); luv_status(L, status); luv_call_callback(L, (luv_handle_t*)handle->data, LUV_CONNECTION, 1); } static int luv_listen(lua_State* L) { uv_stream_t* handle = luv_check_stream(L, 1); int backlog = luaL_checkinteger(L, 2); int ret; luv_check_callback(L, (luv_handle_t*)handle->data, LUV_CONNECTION, 3); ret = uv_listen(handle, backlog, luv_connection_cb); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_accept(lua_State* L) { uv_stream_t* server = luv_check_stream(L, 1); uv_stream_t* client = luv_check_stream(L, 2); int ret = uv_accept(server, client); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static void luv_alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) { (void)handle; buf->base = (char*)malloc(suggested_size); assert(buf->base); buf->len = suggested_size; } static void luv_read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) { lua_State* L = luv_state(handle->loop); int nargs; if (nread > 0) { lua_pushnil(L); lua_pushlstring(L, buf->base, nread); nargs = 2; } free(buf->base); if (nread == 0) return; if (nread == UV_EOF) { nargs = 0; } else if (nread < 0) { luv_status(L, nread); nargs = 1; } luv_call_callback(L, (luv_handle_t*)handle->data, LUV_READ, nargs); } static int luv_read_start(lua_State* L) { uv_stream_t* handle = luv_check_stream(L, 1); int ret; luv_check_callback(L, (luv_handle_t*)handle->data, LUV_READ, 2); ret = uv_read_start(handle, luv_alloc_cb, luv_read_cb); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_read_stop(lua_State* L) { uv_stream_t* handle = luv_check_stream(L, 1); int ret = uv_read_stop(handle); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static void luv_write_cb(uv_write_t* req, int status) { lua_State* L = luv_state(req->handle->loop); luv_status(L, status); luv_fulfill_req(L, (luv_req_t*)req->data, 1); luv_cleanup_req(L, (luv_req_t*)req->data); req->data = NULL; } static uv_buf_t* luv_prep_bufs(lua_State* L, int index, size_t *count) { uv_buf_t *bufs; size_t i; *count = lua_rawlen(L, index); bufs = (uv_buf_t*)malloc(sizeof(uv_buf_t) * *count); for (i = 0; i < *count; ++i) { lua_rawgeti(L, index, i + 1); luv_check_buf(L, -1, &bufs[i]); lua_pop(L, 1); } return bufs; } static int luv_write(lua_State* L) { uv_stream_t* handle = luv_check_stream(L, 1); uv_write_t* req; int ret, ref; ref = luv_check_continuation(L, 3); req = (uv_write_t *)lua_newuserdata(L, sizeof(*req)); req->data = (luv_req_t*)luv_setup_req(L, ref); if (lua_istable(L, 2)) { size_t count; uv_buf_t *bufs = luv_prep_bufs(L, 2, &count); ret = uv_write(req, handle, bufs, count, luv_write_cb); free(bufs); } else if (lua_isstring(L, 2)) { uv_buf_t buf; luv_check_buf(L, 2, &buf); ret = uv_write(req, handle, &buf, 1, luv_write_cb); } else { return luaL_argerror(L, 2, "data must be string or table of strings"); } if (ret < 0) { luv_cleanup_req(L, (luv_req_t*)req->data); lua_pop(L, 1); return luv_error(L, ret); } lua_pushvalue(L, 2); ((luv_req_t*)req->data)->data_ref = luaL_ref(L, LUA_REGISTRYINDEX); return 1; } static int luv_write2(lua_State* L) { uv_stream_t* handle = luv_check_stream(L, 1); uv_write_t* req; int ret, ref; uv_stream_t* send_handle; send_handle = luv_check_stream(L, 3); ref = luv_check_continuation(L, 4); req = (uv_write_t *)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); if (lua_istable(L, 2)) { size_t count; uv_buf_t *bufs = luv_prep_bufs(L, 2, &count); ret = uv_write2(req, handle, bufs, count, send_handle, luv_write_cb); free(bufs); } else if (lua_isstring(L, 2)) { uv_buf_t buf; luv_check_buf(L, 2, &buf); ret = uv_write2(req, handle, &buf, 1, send_handle, luv_write_cb); } else { return luaL_argerror(L, 2, "data must be string or table of strings"); } if (ret < 0) { luv_cleanup_req(L, (luv_req_t*)req->data); lua_pop(L, 1); return luv_error(L, ret); } lua_pushvalue(L, 2); ((luv_req_t*)req->data)->data_ref = luaL_ref(L, LUA_REGISTRYINDEX); return 1; } static int luv_try_write(lua_State* L) { uv_stream_t* handle = luv_check_stream(L, 1); int ret; if (lua_istable(L, 2)) { size_t count; uv_buf_t *bufs = luv_prep_bufs(L, 2, &count); ret = uv_try_write(handle, bufs, count); free(bufs); } else if (lua_isstring(L, 2)) { uv_buf_t buf; luv_check_buf(L, 2, &buf); ret = uv_try_write(handle, &buf, 1); } else { return luaL_argerror(L, 2, "data must be string or table of strings"); } if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_is_readable(lua_State* L) { uv_stream_t* handle = luv_check_stream(L, 1); lua_pushboolean(L, uv_is_readable(handle)); return 1; } static int luv_is_writable(lua_State* L) { uv_stream_t* handle = luv_check_stream(L, 1); lua_pushboolean(L, uv_is_writable(handle)); return 1; } static int luv_stream_set_blocking(lua_State* L) { uv_stream_t* handle = luv_check_stream(L, 1); int blocking, ret; luaL_checktype(L, 2, LUA_TBOOLEAN); blocking = lua_toboolean(L, 2); ret = uv_stream_set_blocking(handle, blocking); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } luv-1.9.1-0/src/tcp.c000066400000000000000000000134611274770366500142340ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "luv.h" static uv_tcp_t* luv_check_tcp(lua_State* L, int index) { uv_tcp_t* handle = (uv_tcp_t*)luv_checkudata(L, index, "uv_tcp"); luaL_argcheck(L, handle->type == UV_TCP && handle->data, index, "Expected uv_tcp_t"); return handle; } static int luv_new_tcp(lua_State* L) { lua_settop(L, 1); uv_tcp_t* handle = (uv_tcp_t*)luv_newuserdata(L, sizeof(*handle)); int ret; if (lua_isnoneornil(L, 1)) { ret = uv_tcp_init(luv_loop(L), handle); } else { ret = uv_tcp_init_ex(luv_loop(L), handle, lua_tointeger(L, 1)); } if (ret < 0) { lua_pop(L, 1); return luv_error(L, ret); } handle->data = luv_setup_handle(L); return 1; } static int luv_tcp_open(lua_State* L) { uv_tcp_t* handle = luv_check_tcp(L, 1); uv_os_sock_t sock = luaL_checkinteger(L, 2); int ret = uv_tcp_open(handle, sock); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_tcp_nodelay(lua_State* L) { uv_tcp_t* handle = luv_check_tcp(L, 1); int ret, enable; luaL_checktype(L, 2, LUA_TBOOLEAN); enable = lua_toboolean(L, 2); ret = uv_tcp_nodelay(handle, enable); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_tcp_keepalive(lua_State* L) { uv_tcp_t* handle = luv_check_tcp(L, 1); int ret, enable; unsigned int delay = 0; luaL_checktype(L, 2, LUA_TBOOLEAN); enable = lua_toboolean(L, 2); if (enable) { delay = luaL_checkinteger(L, 3); } ret = uv_tcp_keepalive(handle, enable, delay); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_tcp_simultaneous_accepts(lua_State* L) { uv_tcp_t* handle = luv_check_tcp(L, 1); int ret, enable; luaL_checktype(L, 2, LUA_TBOOLEAN); enable = lua_toboolean(L, 2); ret = uv_tcp_simultaneous_accepts(handle, enable); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_tcp_bind(lua_State* L) { uv_tcp_t* handle = luv_check_tcp(L, 1); const char* host = luaL_checkstring(L, 2); int port = luaL_checkinteger(L, 3); unsigned int flags = 0; struct sockaddr_storage addr; int ret; if (uv_ip4_addr(host, port, (struct sockaddr_in*)&addr) && uv_ip6_addr(host, port, (struct sockaddr_in6*)&addr)) { return luaL_error(L, "Invalid IP address or port [%s:%d]", host, port); } if (lua_type(L, 4) == LUA_TTABLE) { lua_getfield(L, 4, "ipv6only"); if (lua_toboolean(L, -1)) flags |= UV_TCP_IPV6ONLY; lua_pop(L, 1); } ret = uv_tcp_bind(handle, (struct sockaddr*)&addr, flags); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static void parse_sockaddr(lua_State* L, struct sockaddr_storage* address, int addrlen) { char ip[INET6_ADDRSTRLEN]; int port = 0; lua_newtable(L); if (address->ss_family == AF_INET) { struct sockaddr_in* addrin = (struct sockaddr_in*)address; uv_inet_ntop(AF_INET, &(addrin->sin_addr), ip, addrlen); port = ntohs(addrin->sin_port); } else if (address->ss_family == AF_INET6) { struct sockaddr_in6* addrin6 = (struct sockaddr_in6*)address; uv_inet_ntop(AF_INET6, &(addrin6->sin6_addr), ip, addrlen); port = ntohs(addrin6->sin6_port); } lua_pushstring(L, luv_af_num_to_string(address->ss_family)); lua_setfield(L, -2, "family"); lua_pushinteger(L, port); lua_setfield(L, -2, "port"); lua_pushstring(L, ip); lua_setfield(L, -2, "ip"); } static int luv_tcp_getsockname(lua_State* L) { uv_tcp_t* handle = luv_check_tcp(L, 1); struct sockaddr_storage address; int addrlen = sizeof(address); int ret = uv_tcp_getsockname(handle, (struct sockaddr*)&address, &addrlen); if (ret < 0) return luv_error(L, ret); parse_sockaddr(L, &address, addrlen); return 1; } static int luv_tcp_getpeername(lua_State* L) { uv_tcp_t* handle = luv_check_tcp(L, 1); struct sockaddr_storage address; int addrlen = sizeof(address); int ret = uv_tcp_getpeername(handle, (struct sockaddr*)&address, &addrlen); if (ret < 0) return luv_error(L, ret); parse_sockaddr(L, &address, addrlen); return 1; } static void luv_connect_cb(uv_connect_t* req, int status) { lua_State* L = luv_state(req->handle->loop); luv_status(L, status); luv_fulfill_req(L, (luv_req_t*)req->data, 1); luv_cleanup_req(L, (luv_req_t*)req->data); req->data = NULL; } static int luv_write_queue_size(lua_State* L) { uv_tcp_t* handle = luv_check_tcp(L, 1); lua_pushinteger(L, handle->write_queue_size); return 1; } static int luv_tcp_connect(lua_State* L) { uv_tcp_t* handle = luv_check_tcp(L, 1); const char* host = luaL_checkstring(L, 2); int port = luaL_checkinteger(L, 3); struct sockaddr_storage addr; uv_connect_t* req; int ret, ref; if (uv_ip4_addr(host, port, (struct sockaddr_in*)&addr) && uv_ip6_addr(host, port, (struct sockaddr_in6*)&addr)) { return luaL_error(L, "Invalid IP address or port [%s:%d]", host, port); } ref = luv_check_continuation(L, 4); req = (uv_connect_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); ret = uv_tcp_connect(req, handle, (struct sockaddr*)&addr, luv_connect_cb); if (ret < 0) { luv_cleanup_req(L, (luv_req_t*)req->data); lua_pop(L, 1); return luv_error(L, ret); } return 1; } luv-1.9.1-0/src/thread.c000066400000000000000000000216721274770366500147200ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "luv.h" #include "lthreadpool.h" typedef struct { uv_thread_t handle; char* code; int len; int argc; luv_thread_arg_t arg; } luv_thread_t; static luv_acquire_vm acquire_vm_cb = NULL; static luv_release_vm release_vm_cb = NULL; static lua_State* luv_thread_acquire_vm() { lua_State* L = luaL_newstate(); // Add in the lua standard libraries luaL_openlibs(L); // Get package.loaded, so we can store uv in it. lua_getglobal(L, "package"); lua_getfield(L, -1, "loaded"); lua_remove(L, -2); // Remove package // Store uv module definition at loaded.uv luaopen_luv(L); lua_setfield(L, -2, "luv"); lua_pop(L, 1); return L; } static void luv_thread_release_vm(lua_State* L) { lua_close(L); } static int luv_thread_arg_set(lua_State* L, luv_thread_arg_t* args, int idx, int top, int flag) { int i; idx = idx > 0 ? idx : 1; i = idx; while (i <= top && i <= LUV_THREAD_MAXNUM_ARG + idx) { luv_val_t *arg = args->argv + i - idx; arg->type = lua_type(L, i); switch (arg->type) { case LUA_TNIL: break; case LUA_TBOOLEAN: arg->val.boolean = lua_toboolean(L, i); break; case LUA_TNUMBER: arg->val.num = lua_tonumber(L, i); break; case LUA_TLIGHTUSERDATA: arg->val.userdata = lua_touserdata(L, i); break; case LUA_TSTRING: { const char* p = lua_tolstring(L, i, &arg->val.str.len); arg->val.str.base = (const char*)malloc(arg->val.str.len); if (arg->val.str.base == NULL) { perror("out of memory"); return 0; } memcpy((void*)arg->val.str.base, p, arg->val.str.len); break; } case LUA_TUSERDATA: if (flag == 1) { arg->val.userdata = luv_check_handle(L, i); break; } default: fprintf(stderr, "Error: thread arg not support type '%s' at %d", lua_typename(L, arg->type), i); exit(-1); break; } i++; } args->argc = i - idx; return args->argc; } static void luv_thread_arg_clear(luv_thread_arg_t* args) { int i; for (i = 0; i < args->argc; i++) { if (args->argv[i].type == LUA_TSTRING) { free((void*)args->argv[i].val.str.base); } } memset(args, 0, sizeof(*args)); args->argc = 0; } static void luv_thread_setup_handle(lua_State* L, uv_handle_t* handle) { *(uv_handle_t**) lua_newuserdata(L, sizeof(void*)) = handle; #define XX(uc, lc) case UV_##uc: \ luaL_getmetatable(L, "uv_"#lc); \ break; switch (handle->type) { UV_HANDLE_TYPE_MAP(XX) default: luaL_error(L, "Unknown handle type"); } #undef XX lua_setmetatable(L, -2); } static int luv_thread_arg_push(lua_State* L, const luv_thread_arg_t* args) { int i = 0; while (i < args->argc) { const luv_val_t* arg = args->argv + i; switch (arg->type) { case LUA_TNIL: lua_pushnil(L); break; case LUA_TBOOLEAN: lua_pushboolean(L, arg->val.boolean); break; case LUA_TLIGHTUSERDATA: lua_pushlightuserdata(L, arg->val.userdata); break; case LUA_TNUMBER: lua_pushnumber(L, arg->val.num); break; case LUA_TSTRING: lua_pushlstring(L, arg->val.str.base, arg->val.str.len); break; case LUA_TUSERDATA: luv_thread_setup_handle(L, (uv_handle_t*)arg->val.userdata); break; default: fprintf(stderr, "Error: thread arg not support type %s at %d", lua_typename(L, arg->type), i + 1); } i++; }; return i; } int thread_dump(lua_State* L, const void* p, size_t sz, void* B) { (void)L; luaL_addlstring((luaL_Buffer*) B, (const char*) p, sz); return 0; } static const char* luv_thread_dumped(lua_State* L, int idx, size_t* l) { if (lua_isstring(L, idx)) { return lua_tolstring(L, idx, l); } else { const char* buff = NULL; int top = lua_gettop(L); luaL_Buffer b; luaL_checktype(L, idx, LUA_TFUNCTION); lua_pushvalue(L, idx); luaL_buffinit(L, &b); #if LUA_VERSION_NUM>=503 int test_lua_dump = (lua_dump(L, thread_dump, &b, 1) == 0); #else int test_lua_dump = (lua_dump(L, thread_dump, &b) == 0); #endif if (test_lua_dump) { luaL_pushresult(&b); buff = lua_tolstring(L, -1, l); } else luaL_error(L, "Error: unable to dump given function"); lua_settop(L, top); return buff; } } static luv_thread_t* luv_check_thread(lua_State* L, int index) { luv_thread_t* thread = (luv_thread_t*)luaL_checkudata(L, index, "uv_thread"); return thread; } static int luv_thread_gc(lua_State* L) { luv_thread_t* tid = luv_check_thread(L, 1); free(tid->code); tid->code = NULL; tid->len = 0; luv_thread_arg_clear(&tid->arg); return 0; } static int luv_thread_tostring(lua_State* L) { luv_thread_t* thd = luv_check_thread(L, 1); lua_pushfstring(L, "uv_thread_t: %p", thd->handle); return 1; } static void luv_thread_cb(void* varg) { luv_thread_t* thd = (luv_thread_t*)varg; lua_State* L = acquire_vm_cb(); if (luaL_loadbuffer(L, thd->code, thd->len, "=thread") == 0) { int top = lua_gettop(L); int i = luv_thread_arg_push(L, &thd->arg); for (i = 0; i < thd->arg.argc; i++) { if (thd->arg.argv[i].type == LUA_TUSERDATA) { lua_pushlightuserdata(L, thd->arg.argv[i].val.userdata); lua_pushvalue(L, top + i + 1); lua_rawset(L, LUA_REGISTRYINDEX); } } if (lua_pcall(L, i, 0, 0)) { fprintf(stderr, "Uncaught Error in thread: %s\n", lua_tostring(L, -1)); } for (i = 0; i < thd->arg.argc; i++) { if (thd->arg.argv[i].type == LUA_TUSERDATA) { lua_pushlightuserdata(L, thd->arg.argv[i].val.userdata); lua_rawget(L, LUA_REGISTRYINDEX); lua_pushnil(L); lua_setmetatable(L, -2); lua_pop(L, 1); lua_pushlightuserdata(L, thd->arg.argv[i].val.userdata); lua_pushnil(L); lua_rawset(L, LUA_REGISTRYINDEX); } } } else { fprintf(stderr, "Uncaught Error: %s\n", lua_tostring(L, -1)); } release_vm_cb(L); } static int luv_new_thread(lua_State* L) { int ret; size_t len; const char* buff; luv_thread_t* thread; thread = (luv_thread_t*)lua_newuserdata(L, sizeof(*thread)); memset(thread, 0, sizeof(*thread)); luaL_getmetatable(L, "uv_thread"); lua_setmetatable(L, -2); buff = luv_thread_dumped(L, 1, &len); thread->argc = luv_thread_arg_set(L, &thread->arg, 2, lua_gettop(L) - 1, 1); thread->len = len; thread->code = (char*)malloc(thread->len); memcpy(thread->code, buff, len); ret = uv_thread_create(&thread->handle, luv_thread_cb, thread); if (ret < 0) return luv_error(L, ret); return 1; } static int luv_thread_join(lua_State* L) { luv_thread_t* tid = luv_check_thread(L, 1); int ret = uv_thread_join(&tid->handle); if (ret < 0) return luv_error(L, ret); lua_pushboolean(L, 1); return 1; } static int luv_thread_self(lua_State* L) { luv_thread_t* thread; uv_thread_t t = uv_thread_self(); thread = (luv_thread_t*)lua_newuserdata(L, sizeof(*thread)); memset(thread, 0, sizeof(*thread)); memcpy(&thread->handle, &t, sizeof(t)); luaL_getmetatable(L, "uv_thread"); lua_setmetatable(L, -2); return 1; } static int luv_thread_equal(lua_State* L) { luv_thread_t* t1 = luv_check_thread(L, 1); luv_thread_t* t2 = luv_check_thread(L, 2); int ret = uv_thread_equal(&t1->handle, &t2->handle); lua_pushboolean(L, ret); return 1; } /* Pause the calling thread for a number of milliseconds. */ static int luv_thread_sleep(lua_State* L) { #ifdef _WIN32 DWORD msec = luaL_checkinteger(L, 1); Sleep(msec); #else lua_Integer msec = luaL_checkinteger(L, 1); usleep(msec * 1000); #endif return 0; } static const luaL_Reg luv_thread_methods[] = { {"equal", luv_thread_equal}, {"join", luv_thread_join}, {NULL, NULL} }; static void luv_thread_init(lua_State* L) { luaL_newmetatable(L, "uv_thread"); lua_pushcfunction(L, luv_thread_tostring); lua_setfield(L, -2, "__tostring"); lua_pushcfunction(L, luv_thread_equal); lua_setfield(L, -2, "__eq"); lua_pushcfunction(L, luv_thread_gc); lua_setfield(L, -2, "__gc"); lua_newtable(L); luaL_setfuncs(L, luv_thread_methods, 0); lua_setfield(L, -2, "__index"); lua_pop(L, 1); if (acquire_vm_cb == NULL) acquire_vm_cb = luv_thread_acquire_vm; if (release_vm_cb == NULL) release_vm_cb = luv_thread_release_vm; } LUALIB_API void luv_set_thread_cb(luv_acquire_vm acquire, luv_release_vm release) { acquire_vm_cb = acquire; release_vm_cb = release; } luv-1.9.1-0/src/timer.c000066400000000000000000000050511274770366500145620ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "luv.h" static uv_timer_t* luv_check_timer(lua_State* L, int index) { uv_timer_t* handle = (uv_timer_t*) luv_checkudata(L, index, "uv_timer"); luaL_argcheck(L, handle->type == UV_TIMER && handle->data, index, "Expected uv_timer_t"); return handle; } static int luv_new_timer(lua_State* L) { uv_timer_t* handle = (uv_timer_t*) luv_newuserdata(L, sizeof(*handle)); int ret = uv_timer_init(luv_loop(L), handle); if (ret < 0) { lua_pop(L, 1); return luv_error(L, ret); } handle->data = luv_setup_handle(L); return 1; } static void luv_timer_cb(uv_timer_t* handle) { lua_State* L = luv_state(handle->loop); luv_handle_t* data = (luv_handle_t*)handle->data; luv_call_callback(L, data, LUV_TIMEOUT, 0); } static int luv_timer_start(lua_State* L) { uv_timer_t* handle = luv_check_timer(L, 1); uint64_t timeout; uint64_t repeat; int ret; timeout = luaL_checkinteger(L, 2); repeat = luaL_checkinteger(L, 3); luv_check_callback(L, (luv_handle_t*)handle->data, LUV_TIMEOUT, 4); ret = uv_timer_start(handle, luv_timer_cb, timeout, repeat); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_timer_stop(lua_State* L) { uv_timer_t* handle = luv_check_timer(L, 1); int ret = uv_timer_stop(handle); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_timer_again(lua_State* L) { uv_timer_t* handle = luv_check_timer(L, 1); int ret = uv_timer_again(handle); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_timer_set_repeat(lua_State* L) { uv_timer_t* handle = luv_check_timer(L, 1); uint64_t repeat = luaL_checkinteger(L, 2); uv_timer_set_repeat(handle, repeat); return 0; } static int luv_timer_get_repeat(lua_State* L) { uv_timer_t* handle = luv_check_timer(L, 1); uint64_t repeat = uv_timer_get_repeat(handle); lua_pushinteger(L, repeat); return 1; } luv-1.9.1-0/src/tty.c000066400000000000000000000037331274770366500142670ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "luv.h" static uv_tty_t* luv_check_tty(lua_State* L, int index) { uv_tty_t* handle = (uv_tty_t*)luv_checkudata(L, index, "uv_tty"); luaL_argcheck(L, handle->type == UV_TTY && handle->data, index, "Expected uv_tty_t"); return handle; } static int luv_new_tty(lua_State* L) { int readable, ret; uv_tty_t* handle; uv_file fd = luaL_checkinteger(L, 1); luaL_checktype(L, 2, LUA_TBOOLEAN); readable = lua_toboolean(L, 2); handle = (uv_tty_t*)luv_newuserdata(L, sizeof(*handle)); ret = uv_tty_init(luv_loop(L), handle, fd, readable); if (ret < 0) { lua_pop(L, 1); return luv_error(L, ret); } handle->data = luv_setup_handle(L); return 1; } static int luv_tty_set_mode(lua_State* L) { uv_tty_t* handle = luv_check_tty(L, 1); int mode = luaL_checkinteger(L, 2); int ret = uv_tty_set_mode(handle, mode); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_tty_reset_mode(lua_State* L) { int ret = uv_tty_reset_mode(); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_tty_get_winsize(lua_State* L) { uv_tty_t* handle = luv_check_tty(L, 1); int width, height; int ret = uv_tty_get_winsize(handle, &width, &height); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, width); lua_pushinteger(L, height); return 2; } luv-1.9.1-0/src/udp.c000066400000000000000000000172701274770366500142400ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "luv.h" static uv_udp_t* luv_check_udp(lua_State* L, int index) { uv_udp_t* handle = (uv_udp_t*)luv_checkudata(L, index, "uv_udp"); luaL_argcheck(L, handle->type == UV_UDP && handle->data, index, "Expected uv_udp_t"); return handle; } static int luv_new_udp(lua_State* L) { uv_udp_t* handle = (uv_udp_t*)luv_newuserdata(L, sizeof(*handle)); int ret; if (lua_isnoneornil(L, 1)) { ret = uv_udp_init(luv_loop(L), handle); } else { ret = uv_udp_init_ex(luv_loop(L), handle, lua_tointeger(L, 1)); } if (ret < 0) { lua_pop(L, 1); return luv_error(L, ret); } handle->data = luv_setup_handle(L); return 1; } static int luv_udp_open(lua_State* L) { uv_udp_t* handle = luv_check_udp(L, 1); uv_os_sock_t sock = luaL_checkinteger(L, 2); int ret = uv_udp_open(handle, sock); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_udp_bind(lua_State* L) { uv_udp_t* handle = luv_check_udp(L, 1); const char* host = luaL_checkstring(L, 2); int port = luaL_checkinteger(L, 3); unsigned int flags = 0; struct sockaddr_storage addr; int ret; if (uv_ip4_addr(host, port, (struct sockaddr_in*)&addr) && uv_ip6_addr(host, port, (struct sockaddr_in6*)&addr)) { return luaL_error(L, "Invalid IP address or port [%s:%d]", host, port); } if (lua_type(L, 4) == LUA_TTABLE) { luaL_checktype(L, 4, LUA_TTABLE); lua_getfield(L, 4, "reuseaddr"); if (lua_toboolean(L, -1)) flags |= UV_UDP_REUSEADDR; lua_pop(L, 1); lua_getfield(L, 4, "ipv6only"); if (lua_toboolean(L, -1)) flags |= UV_UDP_IPV6ONLY; lua_pop(L, 1); } ret = uv_udp_bind(handle, (struct sockaddr*)&addr, flags); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_udp_getsockname(lua_State* L) { uv_udp_t* handle = luv_check_udp(L, 1); struct sockaddr_storage address; int addrlen = sizeof(address); int ret = uv_udp_getsockname(handle, (struct sockaddr*)&address, &addrlen); if (ret < 0) return luv_error(L, ret); parse_sockaddr(L, &address, addrlen); return 1; } // These are the same order as uv_membership which also starts at 0 static const char *const luv_membership_opts[] = { "leave", "join", NULL }; static int luv_udp_set_membership(lua_State* L) { uv_udp_t* handle = luv_check_udp(L, 1); const char* multicast_addr = luaL_checkstring(L, 2); const char* interface_addr = luaL_checkstring(L, 3); uv_membership membership = (uv_membership)luaL_checkoption(L, 4, NULL, luv_membership_opts); int ret = uv_udp_set_membership(handle, multicast_addr, interface_addr, membership); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_udp_set_multicast_loop(lua_State* L) { uv_udp_t* handle = luv_check_udp(L, 1); int on, ret; luaL_checktype(L, 2, LUA_TBOOLEAN); on = lua_toboolean(L, 2); ret = uv_udp_set_multicast_loop(handle, on); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_udp_set_multicast_ttl(lua_State* L) { uv_udp_t* handle = luv_check_udp(L, 1); int ttl, ret; ttl = luaL_checkinteger(L, 2); ret = uv_udp_set_multicast_ttl(handle, ttl); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_udp_set_multicast_interface(lua_State* L) { uv_udp_t* handle = luv_check_udp(L, 1); const char* interface_addr = luaL_checkstring(L, 2); int ret = uv_udp_set_multicast_interface(handle, interface_addr); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_udp_set_broadcast(lua_State* L) { uv_udp_t* handle = luv_check_udp(L, 1); int on, ret; luaL_checktype(L, 2, LUA_TBOOLEAN); on = lua_toboolean(L, 2); ret =uv_udp_set_broadcast(handle, on); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_udp_set_ttl(lua_State* L) { uv_udp_t* handle = luv_check_udp(L, 1); int ttl, ret; ttl = luaL_checknumber(L, 2); ret = uv_udp_set_ttl(handle, ttl); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static void luv_udp_send_cb(uv_udp_send_t* req, int status) { lua_State* L = luv_state(req->handle->loop); luv_status(L, status); luv_fulfill_req(L, (luv_req_t*)req->data, 1); luv_cleanup_req(L, (luv_req_t*)req->data); req->data = NULL; } static int luv_udp_send(lua_State* L) { uv_udp_t* handle = luv_check_udp(L, 1); uv_udp_send_t* req; uv_buf_t buf; int ret, port, ref; const char* host; struct sockaddr_storage addr; luv_check_buf(L, 2, &buf); host = luaL_checkstring(L, 3); port = luaL_checkinteger(L, 4); if (uv_ip4_addr(host, port, (struct sockaddr_in*)&addr) && uv_ip6_addr(host, port, (struct sockaddr_in6*)&addr)) { return luaL_error(L, "Invalid IP address or port [%s:%d]", host, port); } ref = luv_check_continuation(L, 5); req = (uv_udp_send_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); ret = uv_udp_send(req, handle, &buf, 1, (struct sockaddr*)&addr, luv_udp_send_cb); if (ret < 0) { luv_cleanup_req(L, (luv_req_t*)req->data); lua_pop(L, 1); return luv_error(L, ret); } return 1; } static int luv_udp_try_send(lua_State* L) { uv_udp_t* handle = luv_check_udp(L, 1); uv_buf_t buf; int ret, port; const char* host; struct sockaddr_storage addr; luv_check_buf(L, 2, &buf); host = luaL_checkstring(L, 3); port = luaL_checkinteger(L, 4); if (uv_ip4_addr(host, port, (struct sockaddr_in*)&addr) && uv_ip6_addr(host, port, (struct sockaddr_in6*)&addr)) { return luaL_error(L, "Invalid IP address or port [%s:%d]", host, port); } ret = uv_udp_try_send(handle, &buf, 1, (struct sockaddr*)&addr); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static void luv_udp_recv_cb(uv_udp_t* handle, ssize_t nread, const uv_buf_t* buf, const struct sockaddr* addr, unsigned flags) { lua_State* L = luv_state(handle->loop); // err if (nread < 0) { luv_status(L, nread); } else { lua_pushnil(L); } // data if (nread == 0) { if (addr) { lua_pushstring(L, ""); } else { lua_pushnil(L); } } else if (nread > 0) { lua_pushlstring(L, buf->base, nread); } if (buf) free(buf->base); // address if (addr) { parse_sockaddr(L, (struct sockaddr_storage*)addr, sizeof *addr); } else { lua_pushnil(L); } // flags lua_newtable(L); if (flags & UV_UDP_PARTIAL) { lua_pushboolean(L, 1); lua_setfield(L, -2, "partial"); } luv_call_callback(L, (luv_handle_t*)handle->data, LUV_RECV, 4); } static int luv_udp_recv_start(lua_State* L) { uv_udp_t* handle = luv_check_udp(L, 1); int ret; luv_check_callback(L, (luv_handle_t*)handle->data, LUV_RECV, 2); ret = uv_udp_recv_start(handle, luv_alloc_cb, luv_udp_recv_cb); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } static int luv_udp_recv_stop(lua_State* L) { uv_udp_t* handle = luv_check_udp(L, 1); int ret = uv_udp_recv_stop(handle); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; } luv-1.9.1-0/src/util.c000066400000000000000000000033661274770366500144260ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "luv.h" void luv_stack_dump(lua_State* L, const char* name) { int i, l; fprintf(stderr, "\nAPI STACK DUMP %p %d: %s\n", L, lua_status(L), name); for (i = 1, l = lua_gettop(L); i <= l; i++) { int type = lua_type(L, i); switch (type) { case LUA_TSTRING: fprintf(stderr, " %d %s \"%s\"\n", i, lua_typename(L, type), lua_tostring(L, i)); break; case LUA_TNUMBER: fprintf(stderr, " %d %s %ld\n", i, lua_typename(L, type), (long int) lua_tointeger(L, i)); break; case LUA_TUSERDATA: fprintf(stderr, " %d %s %p\n", i, lua_typename(L, type), lua_touserdata(L, i)); break; default: fprintf(stderr, " %d %s\n", i, lua_typename(L, type)); break; } } assert(l == lua_gettop(L)); } static int luv_error(lua_State* L, int status) { lua_pushnil(L); lua_pushfstring(L, "%s: %s", uv_err_name(status), uv_strerror(status)); lua_pushstring(L, uv_err_name(status)); return 3; } static void luv_status(lua_State* L, int status) { if (status < 0) { lua_pushstring(L, uv_err_name(status)); } else { lua_pushnil(L); } } luv-1.9.1-0/src/util.h000066400000000000000000000015211274770366500144220ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef LUV_UTIL_H #define LUV_UTIL_H #include "luv.h" void luv_stack_dump(lua_State* L, const char* name); static int luv_error(lua_State* L, int ret); static void luv_status(lua_State* L, int status); #endif luv-1.9.1-0/src/work.c000066400000000000000000000132521274770366500144260ustar00rootroot00000000000000/* * Copyright 2014 The Luvit Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "luv.h" #include "lthreadpool.h" typedef struct { lua_State* L; /* vm in main */ char* code; /* thread entry code */ size_t len; uv_async_t async; int async_cb; /* ref, run in main, call when async message received, NYI */ int after_work_cb; /* ref, run in main ,call after work cb*/ } luv_work_ctx_t; typedef struct { uv_work_t work; luv_work_ctx_t* ctx; luv_thread_arg_t arg; } luv_work_t; static uv_key_t L_key; static luv_work_ctx_t* luv_check_work_ctx(lua_State* L, int index) { luv_work_ctx_t* ctx = (luv_work_ctx_t*)luaL_checkudata(L, index, "luv_work_ctx"); return ctx; } static int luv_work_ctx_gc(lua_State *L) { luv_work_ctx_t* ctx = luv_check_work_ctx(L, 1); free(ctx->code); luaL_unref(L, LUA_REGISTRYINDEX, ctx->after_work_cb); luaL_unref(L, LUA_REGISTRYINDEX, ctx->async_cb); return 0; } static int luv_work_ctx_tostring(lua_State* L) { luv_work_ctx_t* ctx = luv_check_work_ctx(L, 1); lua_pushfstring(L, "luv_work_ctx_t: %p", ctx); return 1; } static void luv_work_cb(uv_work_t* req) { luv_work_t* work = (luv_work_t*)req->data; luv_work_ctx_t* ctx = work->ctx; lua_State *L = (lua_State *)uv_key_get(&L_key); int top; if (L == NULL) { /* vm reuse in threadpool */ L = acquire_vm_cb(); uv_key_set(&L_key, L); } top = lua_gettop(L); lua_pushlstring(L, ctx->code, ctx->len); lua_rawget(L, LUA_REGISTRYINDEX); if (lua_isnil(L, -1)) { lua_pop(L, 1); lua_pushlstring(L, ctx->code, ctx->len); if (luaL_loadbuffer(L, ctx->code, ctx->len, "=pool") != 0) { fprintf(stderr, "Uncaught Error: %s\n", lua_tostring(L, -1)); lua_pop(L, 2); lua_pushnil(L); } else { lua_pushvalue(L, -1); lua_insert(L, lua_gettop(L) - 2); lua_rawset(L, LUA_REGISTRYINDEX); } } if (lua_isfunction(L, -1)) { int i = luv_thread_arg_push(L, &work->arg); if (lua_pcall(L, i, LUA_MULTRET, 0)) { fprintf(stderr, "Uncaught Error in thread: %s\n", lua_tostring(L, -1)); } luv_thread_arg_clear(&work->arg); luv_thread_arg_set(L, &work->arg, top + 1, lua_gettop(L), 0); lua_settop(L, top); } else { fprintf(stderr, "Uncaught Error: %s can't be work entry\n", lua_typename(L, lua_type(L,-1))); } } static void luv_after_work_cb(uv_work_t* req, int status) { luv_work_t* work = (luv_work_t*)req->data; luv_work_ctx_t* ctx = work->ctx; lua_State*L = ctx->L; int i; (void)status; lua_rawgeti(L, LUA_REGISTRYINDEX, ctx->after_work_cb); i = luv_thread_arg_push(L, &work->arg); if (lua_pcall(L, i, 0, 0)) { fprintf(stderr, "Uncaught Error in thread: %s\n", lua_tostring(L, -1)); } //ref down to ctx lua_pushlightuserdata(L, work); lua_pushnil(L); lua_rawset(L, LUA_REGISTRYINDEX); luv_thread_arg_clear(&work->arg); free(work); } static void async_cb(uv_async_t *handle) { luv_work_t* work = (luv_work_t*)handle->data; luv_work_ctx_t* ctx = work->ctx; lua_State*L = ctx->L; int i; lua_rawgeti(L, LUA_REGISTRYINDEX, ctx->async_cb); i = luv_thread_arg_push(L, &work->arg); if (lua_pcall(L, i, 0, 0)) { fprintf(stderr, "Uncaught Error in thread: %s\n", lua_tostring(L, -1)); } } static int luv_new_work(lua_State* L) { size_t len; const char* buff; luv_work_ctx_t* ctx; buff = luv_thread_dumped(L, 1, &len); luaL_checktype(L, 2, LUA_TFUNCTION); if(!lua_isnoneornil(L, 3)) luaL_checktype(L, 3, LUA_TFUNCTION); ctx = (luv_work_ctx_t*)lua_newuserdata(L, sizeof(*ctx)); memset(ctx, 0, sizeof(*ctx)); ctx->len = len; ctx->code = (char*)malloc(ctx->len); memcpy(ctx->code, buff, len); lua_pushvalue(L, 2); ctx->after_work_cb = luaL_ref(L, LUA_REGISTRYINDEX); if (lua_gettop(L) == 4) { lua_pushvalue(L, 3); ctx->async_cb = luaL_ref(L, LUA_REGISTRYINDEX); uv_async_init(luv_loop(L), &ctx->async, async_cb); } else ctx->async_cb = LUA_REFNIL; ctx->L = L; luaL_getmetatable(L, "luv_work_ctx"); lua_setmetatable(L, -2); return 1; } static int luv_queue_work(lua_State* L) { int top = lua_gettop(L); luv_work_ctx_t* ctx = luv_check_work_ctx(L, 1); luv_work_t* work = (luv_work_t*)malloc(sizeof(*work)); int ret; luv_thread_arg_set(L, &work->arg, 2, top, 0); work->ctx = ctx; work->work.data = work; ret = uv_queue_work(luv_loop(L), &work->work, luv_work_cb, luv_after_work_cb); if (ret < 0) { free(work); return luv_error(L, ret); } //ref up to ctx lua_pushlightuserdata(L, work); lua_pushvalue(L, 1); lua_rawset(L, LUA_REGISTRYINDEX); lua_pushboolean(L, 1); return 1; } static const luaL_Reg luv_work_ctx_methods[] = { {"queue", luv_queue_work}, {NULL, NULL} }; static int key_inited = 0; static void luv_work_init(lua_State* L) { luaL_newmetatable(L, "luv_work_ctx"); lua_pushcfunction(L, luv_work_ctx_tostring); lua_setfield(L, -2, "__tostring"); lua_pushcfunction(L, luv_work_ctx_gc); lua_setfield(L, -2, "__gc"); lua_newtable(L); luaL_setfuncs(L, luv_work_ctx_methods, 0); lua_setfield(L, -2, "__index"); lua_pop(L, 1); if (key_inited==0) { key_inited = 1; uv_key_create(&L_key); } } luv-1.9.1-0/tests/000077500000000000000000000000001274770366500136505ustar00rootroot00000000000000luv-1.9.1-0/tests/manual-test-cluster.lua000066400000000000000000000133171274770366500202710ustar00rootroot00000000000000-- This is quite the involved test. Basically it binds -- to a tcp port, spawns n children (one per CPU core) -- who all listen on the same shared port and act as a -- load balancing cluster. -- Then N clients are spawned that connect to the cluster -- The application itself kills the worker upon connection -- All N workers should accept exactly one request and all close. return require('lib/tap')(function (test) -- This function will be run in a child process local worker_code = string.dump(function () local dump = require('lib/utils').dump local function print(...) local n = select('#', ...) local arguments = {...} for i = 1, n do arguments[i] = tostring(arguments[i]) end local text = table.concat(arguments, "\t") text = " " .. string.gsub(text, "\n", "\n ") _G.print(text) end local function p(...) local n = select('#', ...) local arguments = { ... } for i = 1, n do arguments[i] = dump(arguments[i]) end print(table.concat(arguments, "\t")) end local uv = require('luv') local answer = -1 -- The parent is going to pass us the server handle over a pipe -- This will be our local file descriptor at PIPE_FD local pipe = uv.new_pipe(true) local pipe_fd = tonumber(os.getenv("PIPE_FD")) assert(uv.pipe_open(pipe, pipe_fd)) -- Configure the server handle local server = uv.new_tcp() local done = false local function onconnection() print("NOT ACCEPTING, already done") if done then return end local client = uv.new_tcp() assert(uv.accept(server, client)) p("New TCP", client, "on", server) p{client=client} assert(uv.write(client, "BYE!\n")); assert(uv.shutdown(client, function () uv.close(client) uv.unref(server) done = true answer = 42 end)) end -- Read the server handle from the parent local function onread(err, data) p("onread", {err=err,data=data}) assert(not err, err) if uv.pipe_pending_count(pipe) > 0 then local pending_type = uv.pipe_pending_type(pipe) p("pending_type", pending_type) assert(pending_type == "tcp") assert(uv.accept(pipe, server)) assert(uv.listen(server, 0, onconnection)) p("Received server handle from parent process", server) elseif data then p("ondata", data) else p("onend", data) end end uv.read_start(pipe, onread) -- Start the event loop! uv.run() os.exit(answer) end) local client_code = string.dump(function () local dump = require('lib/utils').dump local function print(...) local n = select('#', ...) local arguments = {...} for i = 1, n do arguments[i] = tostring(arguments[i]) end local text = table.concat(arguments, "\t") text = " " .. string.gsub(text, "\n", "\n ") _G.print(text) end local function p(...) local n = select('#', ...) local arguments = { ... } for i = 1, n do arguments[i] = dump(arguments[i]) end print(table.concat(arguments, "\t")) end local uv = require('luv') local host = os.getenv("HOST") local port = tonumber(os.getenv("PORT")) local socket = uv.new_tcp() assert(uv.tcp_connect(socket, host, port, function (err) p("client connected", {err=err}) assert(not err, err) end)) -- Start the event loop! uv.run() end) test("tcp cluster", function (print, p, expect, uv) local exepath = assert(uv.exepath()) local cpu_count = # assert(uv.cpu_info()) local left = cpu_count local server = uv.new_tcp() assert(uv.tcp_bind(server, "::1", 0)) local address = uv.tcp_getsockname(server) p{server=server,address=address} print("Master process bound to TCP port " .. address.port .. " on " .. address.ip) local function spawnWorker() local pipe = uv.new_pipe(true) local input = uv.new_pipe(false) local child, pid child, pid = assert(uv.spawn(exepath, { cwd = uv.cwd(), stdio = {input,1,2,pipe}, env= {"PIPE_FD=3"} }, expect(function (status, signal) p("Worker exited", {status=status,signal=signal}) assert(status == 42, "worker should return 42") assert(signal == 0) left = left - 1 uv.close(child) uv.close(input) uv.close(pipe) if left == 0 then p("All workers are now dead") uv.close(server) end end))) p("Spawned worker", pid, "and sending handle", server) assert(uv.write(input, worker_code)) assert(uv.write2(pipe, "123", server)) assert(uv.shutdown(input)) assert(uv.shutdown(pipe)) end local function spawnClient() local input = uv.new_pipe(false) local child, pid child, pid = assert(uv.spawn(exepath, { stdio = {input,1,2}, cwd = uv.cwd(), env= { "HOST=" .. address.ip, "PORT=" .. address.port, } }, expect(function (status, signal) p("Client exited", {status=status,signal=signal}) assert(status == 0) assert(signal == 0) uv.close(child) end, left))) p("Spawned client", pid) assert(uv.write(input, client_code)) assert(uv.shutdown(input)) uv.close(input) end -- Spawn a child process for each CPU core for _ = 1, cpu_count do spawnWorker() end -- Spawn the clients after a short delay local timer = uv.new_timer() uv.timer_start(timer, 1000, 0, expect(function () for _ = 1, cpu_count do spawnClient() end uv.close(timer) end)) end) end) luv-1.9.1-0/tests/run.lua000066400000000000000000000013121274770366500151540ustar00rootroot00000000000000-- Run this from the parent directory as -- -- luajit tests/run.lua -- local tap = require("lib/tap") local uv = require("luv") local isWindows if jit and jit.os then -- Luajit provides explicit platform detection isWindows = jit.os == "Windows" else -- Normal lua will only have \ for path separator on windows. isWindows = package.config:find("\\") and true or false end _G.isWindows = isWindows local req = uv.fs_scandir("tests") while true do local name = uv.fs_scandir_next(req) if not name then break end local match = string.match(name, "^test%-(.*).lua$") if match then local path = "tests/test-" .. match tap(match) require(path) end end -- run the tests! tap(true) luv-1.9.1-0/tests/test-async.lua000066400000000000000000000017351274770366500164530ustar00rootroot00000000000000return require('lib/tap')(function (test) test("test pass async between threads", function(p, p, expect, uv) local before = os.time() local async async = uv.new_async(expect(function (a,b,c) p('in async notify callback') p(a,b,c) assert(a=='a') assert(b==true) assert(c==250) uv.close(async) end)) local args = {500, 'string', nil, false, 5, "helloworld",async} local unpack = unpack or table.unpack uv.new_thread(function(num,s,null,bool,five,hw,asy) local uv = require'luv' assert(type(num) == "number") assert(type(s) == "string") assert(null == nil) assert(bool == false) assert(five == 5) assert(hw == 'helloworld') assert(type(asy)=='userdata') assert(uv.async_send(asy,'a',true,250)==0) uv.sleep(1000) end, unpack(args)):join() local elapsed = (os.time() - before) * 1000 assert(elapsed >= 1000, "elapsed should be at least delay ") end) end) luv-1.9.1-0/tests/test-conversions.lua000066400000000000000000000003601274770366500176770ustar00rootroot00000000000000return require('lib/tap')(function (test) test("basic 64bit conversions", function (print, p, expect, uv) assert(string.format("%x", 29913653248) == "6f6fe2000") assert(string.format("%x", 32207650816) == "77fb9c000") end) end) luv-1.9.1-0/tests/test-dns.lua000066400000000000000000000067511274770366500161250ustar00rootroot00000000000000return require('lib/tap')(function (test) test("Get all local http addresses", function (print, p, expect, uv) assert(uv.getaddrinfo(nil, "http", nil, expect(function (err, res) p(res, #res) assert(not err, err) assert(res[1].port == 80) end))) end) test("Get all local http addresses sync", function (print, p, expect, uv) local res = assert(uv.getaddrinfo(nil, "http")) p(res, #res) assert(res[1].port == 80) end) test("Get only ipv4 tcp adresses for luvit.io", function (print, p, expect, uv) assert(uv.getaddrinfo("luvit.io", nil, { socktype = "stream", family = "inet", }, expect(function (err, res) assert(not err, err) p(res, #res) assert(#res == 1) end))) end) -- FIXME: this test always fails on AppVeyor for some reason if _G.isWindows and not os.getenv'APPVEYOR' then test("Get only ipv6 tcp adresses for luvit.io", function (print, p, expect, uv) assert(uv.getaddrinfo("luvit.io", nil, { socktype = "stream", family = "inet6", }, expect(function (err, res) assert(not err, err) p(res, #res) assert(#res == 1) end))) end) end test("Get ipv4 and ipv6 tcp adresses for luvit.io", function (print, p, expect, uv) assert(uv.getaddrinfo("luvit.io", nil, { socktype = "stream", }, expect(function (err, res) assert(not err, err) p(res, #res) assert(#res > 0) end))) end) test("Get all adresses for luvit.io", function (print, p, expect, uv) assert(uv.getaddrinfo("luvit.io", nil, nil, expect(function (err, res) assert(not err, err) p(res, #res) assert(#res > 0) end))) end) test("Lookup local ipv4 address", function (print, p, expect, uv) assert(uv.getnameinfo({ family = "inet", }, expect(function (err, hostname, service) p{err=err,hostname=hostname,service=service} assert(not err, err) assert(hostname) assert(service) end))) end) test("Lookup local ipv4 address sync", function (print, p, expect, uv) local hostname, service = assert(uv.getnameinfo({ family = "inet", })) p{hostname=hostname,service=service} assert(hostname) assert(service) end) test("Lookup local 127.0.0.1 ipv4 address", function (print, p, expect, uv) assert(uv.getnameinfo({ ip = "127.0.0.1", }, expect(function (err, hostname, service) p{err=err,hostname=hostname,service=service} assert(not err, err) assert(hostname) assert(service) end))) end) test("Lookup local ipv6 address", function (print, p, expect, uv) assert(uv.getnameinfo({ family = "inet6", }, expect(function (err, hostname, service) p{err=err,hostname=hostname,service=service} assert(not err, err) assert(hostname) assert(service) end))) end) test("Lookup local ::1 ipv6 address", function (print, p, expect, uv) assert(uv.getnameinfo({ ip = "::1", }, expect(function (err, hostname, service) p{err=err,hostname=hostname,service=service} assert(not err, err) assert(hostname) assert(service) end))) end) test("Lookup local port 80 service", function (print, p, expect, uv) assert(uv.getnameinfo({ port = 80, family = "inet6", }, expect(function (err, hostname, service) p{err=err,hostname=hostname,service=service} assert(not err, err) assert(hostname) assert(service == "http") end))) end) end) luv-1.9.1-0/tests/test-fs.lua000066400000000000000000000050461274770366500157450ustar00rootroot00000000000000return require('lib/tap')(function (test) test("read a file sync", function (print, p, expect, uv) local fd = assert(uv.fs_open('README.md', 'r', tonumber('644', 8))) p{fd=fd} local stat = assert(uv.fs_fstat(fd)) p{stat=stat} local chunk = assert(uv.fs_read(fd, stat.size, 0)) assert(#chunk == stat.size) assert(uv.fs_close(fd)) end) test("read a file async", function (print, p, expect, uv) uv.fs_open('README.md', 'r', tonumber('644', 8), expect(function (err, fd) assert(not err, err) p{fd=fd} uv.fs_fstat(fd, expect(function (err, stat) assert(not err, err) p{stat=stat} uv.fs_read(fd, stat.size, 0, expect(function (err, chunk) assert(not err, err) p{chunk=#chunk} assert(#chunk == stat.size) uv.fs_close(fd, expect(function (err) assert(not err, err) end)) end)) end)) end)) end) test("fs.write", function (print, p, expect, uv) local path = "_test_" local fd = assert(uv.fs_open(path, "w", 438)) uv.fs_write(fd, "Hello World\n", -1) uv.fs_write(fd, {"with\n", "more\n", "lines\n"}, -1) uv.fs_close(fd) uv.fs_unlink(path) end) test("fs.stat sync", function (print, p, expect, uv) local stat = assert(uv.fs_stat("README.md")) assert(stat.size) end) test("fs.stat async", function (print, p, expect, uv) assert(uv.fs_stat("README.md", expect(function (err, stat) assert(not err, err) assert(stat.size) end))) end) test("fs.stat sync error", function (print, p, expect, uv) local stat, err, code = uv.fs_stat("BAD_FILE!") p{err=err,code=code,stat=stat} assert(not stat) assert(err) assert(code == "ENOENT") end) test("fs.stat async error", function (print, p, expect, uv) assert(uv.fs_stat("BAD_FILE@", expect(function (err, stat) p{err=err,stat=stat} assert(err) assert(not stat) end))) end) test("fs.scandir", function (print, p, expect, uv) local req = uv.fs_scandir('.') local function iter() return uv.fs_scandir_next(req) end for name, ftype in iter do p{name=name, ftype=ftype} assert(name) -- ftype is not available in all filesystems; for example it's -- provided for HFS+ (OSX), NTFS (Windows) but not for ext4 (Linux). end end) test("fs.realpath", function (print, p, expect, uv) p(assert(uv.fs_realpath('.'))) assert(uv.fs_realpath('.', expect(function (err, path) assert(not err, err) p(path) end))) end) end) luv-1.9.1-0/tests/test-leaks.lua000066400000000000000000000115241274770366500164320ustar00rootroot00000000000000return require('lib/tap')(function (test) local function bench(uv, p, count, fn) collectgarbage() local before local notify = count / 8 for i = 1, count do fn() if i % notify == 0 then uv.run() collectgarbage() local now = uv.resident_set_memory() if not before then before = now end p(i, now) end end uv.run() collectgarbage() local after = uv.resident_set_memory() p{ before = before, after = after, } assert(after < before * 1.5) end test("fs-write", function (print, p, expect, uv) bench(uv, p, 0xf00, function () local path = "_test_" local fd = assert(uv.fs_open(path, "w", 438)) uv.fs_write(fd, "Hello World\n", -1) uv.fs_write(fd, {"with\n", "more\n", "lines\n"}, -1) uv.fs_close(fd) uv.fs_unlink(path) end) end) test("lots-o-timers", function (print, p, expect, uv) bench(uv, p, 0x100000, function () local timer = uv.new_timer() uv.close(timer) end) end) test("lots-o-timers with canceled callbacks", function (print, p, expect, uv) bench(uv, p, 0x10000, function () local timer = uv.new_timer() uv.timer_start(timer, 100, 100, function () end) uv.timer_stop(timer) uv.close(timer, function () end) uv.run() end) end) test("lots-o-timers with real timeouts", function (print, p, expect, uv) bench(uv, p, 0x500, function () local timer = uv.new_timer() uv.timer_start(timer, 10, 0, expect(function () uv.timer_stop(timer) uv.close(timer, function () end) end)) end) end) test("reading file async", function (print, p, expect, uv) local mode = tonumber("644", 8) bench(uv, p, 0x500, function () local onOpen, onStat, onRead, onClose local fd, stat onOpen = expect(function (err, result) assert(not err, err) fd = result uv.fs_fstat(fd, onStat) end) onStat = expect(function (err, result) assert(not err, err) stat = result uv.fs_read(fd, stat.size, 0, onRead) end) onRead = expect(function (err, data) assert(not err, err) assert(#data == stat.size) uv.fs_close(fd, onClose) end) onClose = expect(function (err) assert(not err, err) end) assert(uv.fs_open("README.md", "r", mode, onOpen)) end) end) test("reading file sync", function (print, p, expect, uv) local mode = tonumber("644", 8) bench(uv, p, 0x2000, function () local fd = assert(uv.fs_open("README.md", "r", mode)) local stat = assert(uv.fs_fstat(fd)) local data = assert(uv.fs_read(fd, stat.size, 0)) assert(#data == stat.size) assert(uv.fs_close(fd)) end) end) test("invalid file", function (print, p, expect, uv) local mode = tonumber("644", 8) bench(uv, p, 0x1500, function () local req = uv.fs_open("BAD_FILE", "r", mode, expect(function (err, fd) assert(not fd) assert(err) end)) end) end) test("invalid file sync", function (print, p, expect, uv) local mode = tonumber("644", 8) bench(uv, p, 0x20000, function () local fd, err = uv.fs_open("BAD_FILE", "r", mode) assert(not fd) assert(err) end) end) test("invalid spawn args", function (print, p, expect, uv) -- Regression test for #73 bench(uv, p, 0x10000, function () local ret, err = pcall(function () return uv.spawn("ls", { args = {"-l", "-h"}, stdio = {0, 1, 2}, env = {"EXTRA=true"}, gid = false, -- Should be integer }) end) assert(not ret) assert(err) end) end) test("stream writing with string and array", function (print, p, expect, uv) local port = 0 local server = uv.new_tcp() local data local count = 0x800 server:unref() server:bind("127.0.0.1", port) server:listen(128, expect(function (err) assert(not err, err) local client = uv.new_tcp() server:accept(client) client:write(data) client:read_start(expect(function (err, data) assert(not err, err) assert(data) client:close() end)) end, count)) local address = server:getsockname() bench(uv, p, count, function () data = string.rep("Hello", 500) local socket = uv.new_tcp() socket:connect(address.ip, address.port, expect(function (err) assert(not err, err) socket:read_start(expect(function (err, chunk) assert(not err, err) assert(chunk) local data = {} for i = 0, 100 do data[i + 1] = string.rep(string.char(i), 100) end socket:write(data) socket:close() end)) end)) uv.run() end) server:close() end) end) luv-1.9.1-0/tests/test-misc.lua000066400000000000000000000045751274770366500162760ustar00rootroot00000000000000return require('lib/tap')(function (test) test("uv.guess_handle", function (print, p, expect, uv) local types = { [0] = assert(uv.guess_handle(0)), assert(uv.guess_handle(1)), assert(uv.guess_handle(2)), } p("stdio fd types", types) end) test("uv.version and uv.version_string", function (print, p, expect, uv) local version = assert(uv.version()) local version_string = assert(uv.version_string()) p{version=version, version_string=version_string} assert(type(version) == "number") assert(type(version_string) == "string") end) test("memory size", function (print, p, expect, uv) local rss = uv.resident_set_memory() local total = uv.get_total_memory() local free = uv.get_free_memory() p{rss=rss,total=total,free=free} assert(rss < total) end) test("uv.uptime", function (print, p, expect, uv) local uptime = assert(uv.uptime()) p{uptime=uptime} end) test("uv.getrusage", function (print, p, expect, uv) local rusage = assert(uv.getrusage()) p(rusage) end) test("uv.cpu_info", function (print, p, expect, uv) local info = assert(uv.cpu_info()) p(info) end) test("uv.interface_addresses", function (print, p, expect, uv) local addresses = assert(uv.interface_addresses()) for name, info in pairs(addresses) do p(name, addresses[name]) end end) test("uv.loadavg", function (print, p, expect, uv) local avg = {assert(uv.loadavg())} p(avg) assert(#avg == 3) end) test("uv.exepath", function (print, p, expect, uv) local path = assert(uv.exepath()) p(path) end) test("uv.os_homedir", function (print, p, expect, uv) local path = assert(uv.os_homedir()) p(path) end) test("uv.os_tmpdir", function (print, p, expect, uv) local path = assert(uv.os_tmpdir()) p(path) end) test("uv.os_get_passwd", function (print, p, expect, uv) local passwd = assert(uv.os_get_passwd()) p(passwd) end) test("uv.cwd and uv.chdir", function (print, p, expect, uv) local old = assert(uv.cwd()) p(old) assert(uv.chdir("/")) local cwd = assert(uv.cwd()) p(cwd) assert(cwd ~= old) assert(uv.chdir(old)) end) test("uv.hrtime", function (print, p, expect, uv) local time = assert(uv.hrtime()) p(time) end) test("test_getpid", function (print, p, expect, uv) assert(uv.getpid()) end) end) luv-1.9.1-0/tests/test-prepare-check-idle-async.lua000066400000000000000000000022611274770366500220700ustar00rootroot00000000000000return require('lib/tap')(function (test) test("simple prepare", function (print, p, expect, uv) local prepare = uv.new_prepare() uv.prepare_start(prepare, expect(function () p("prepare", prepare) uv.prepare_stop(prepare) uv.close(prepare, expect(function () end)) end)) end) test("simple check", function (print, p, expect, uv) local check = uv.new_check() uv.check_start(check, expect(function () p("check", check) uv.check_stop(check) uv.close(check, expect(function () end)) end)) -- Trigger with a timer local timer = uv.new_timer() uv.timer_start(timer, 10, 0, expect(function() p("timeout", timer) uv.timer_stop(timer) uv.close(timer) end)) end) test("simple idle", function (print, p, expect, uv) local idle = uv.new_idle() uv.idle_start(idle, expect(function () p("idle", idle) uv.idle_stop(idle) uv.close(idle, expect(function () end)) end)) end) test("simple async", function (print, p, expect, uv) local async async = uv.new_async(expect(function () uv.close(async) end)) uv.async_send(async) end) end) luv-1.9.1-0/tests/test-process.lua000066400000000000000000000046171274770366500170160ustar00rootroot00000000000000return require('lib/tap')(function (test) test("test disable_stdio_inheritance", function (print, p, expect, uv) uv.disable_stdio_inheritance() end) test("process stdout", function (print, p, expect, uv) local stdout = uv.new_pipe(false) local handle, pid handle, pid = uv.spawn(uv.exepath(), { args = {"-e", "print 'Hello World'"}, stdio = {nil, stdout}, }, expect(function (code, signal) p("exit", {code=code, signal=signal}) uv.close(handle) end)) p{ handle=handle, pid=pid } uv.read_start(stdout, expect(function (err, chunk) p("stdout", {err=err,chunk=chunk}) assert(not err, err) uv.close(stdout) end)) end) if _G.isWindows then return end test("spawn and kill by pid", function (print, p, expect, uv) local handle, pid handle, pid = uv.spawn("sleep", { args = {1}, }, expect(function (status, signal) p("exit", handle, {status=status,signal=signal}) assert(status == 0) assert(signal == 2) uv.close(handle) end)) p{handle=handle,pid=pid} uv.kill(pid, "sigint") end) test("spawn and kill by handle", function (print, p, expect, uv) local handle, pid handle, pid = uv.spawn("sleep", { args = {1}, }, expect(function (status, signal) p("exit", handle, {status=status,signal=signal}) assert(status == 0) assert(signal == 15) uv.close(handle) end)) p{handle=handle,pid=pid} uv.process_kill(handle, "sigterm") end) test("invalid command", function (print, p, expect, uv) local handle, err handle, err = uv.spawn("ksjdfksjdflkjsflksdf", {}, function(exit, code) assert(false) end) assert(handle == nil) assert(err) end) test("process stdio", function (print, p, expect, uv) local stdin = uv.new_pipe(false) local stdout = uv.new_pipe(false) local handle, pid handle, pid = uv.spawn("cat", { stdio = {stdin, stdout}, }, expect(function (code, signal) p("exit", {code=code, signal=signal}) uv.close(handle) end)) p{ handle=handle, pid=pid } uv.read_start(stdout, expect(function (err, chunk) p("stdout", {err=err,chunk=chunk}) assert(not err, err) uv.close(stdout) end)) uv.write(stdin, "Hello World") uv.shutdown(stdin, expect(function () uv.close(stdin) end)) end) end) luv-1.9.1-0/tests/test-sigchld-after-lua_close.sh000077500000000000000000000024701274770366500216470ustar00rootroot00000000000000#!/bin/sh # Verifies that luv will cleanup libuv process handles correctly even if # not done by "userspace". # Details: https://github.com/luvit/luv/issues/193 # This test modifies one of the examples to skip libuv process cleanup, # purposely making it leave SIGCHLD signal handler. # patch -p1 << "EOF" diff --git a/examples/talking-to-children.lua b/examples/talking-to-children.lua index 10a53ef..6c6c53f 100644 --- a/examples/talking-to-children.lua +++ b/examples/talking-to-children.lua @@ -41,7 +41,3 @@ uv.read_start(stdout, onread) uv.read_start(stderr, onread) uv.write(stdin, "Hello World") uv.shutdown(stdin, onshutdown) - -uv.run() -uv.walk(uv.close) -uv.run() EOF # It also requires a patched lua standalone interpreter that sends SIGCHLD to # itself after calling lua_close, which would have freed all memory of the libuv # event loop associated with the lua state. ( cd deps/lua patch -p1 << "EOF" diff --git a/src/lua.c b/src/lua.c index 7a47582..4dc19d5 100644 --- a/src/lua.c +++ b/src/lua.c @@ -608,6 +608,7 @@ int main (int argc, char **argv) { result = lua_toboolean(L, -1); /* get result */ report(L, status); lua_close(L); + kill(0, SIGCHLD); return (result && status == LUA_OK) ? EXIT_SUCCESS : EXIT_FAILURE; } EOF ) WITH_LUA_ENGINE=Lua make ./build/lua examples/talking-to-children.lua luv-1.9.1-0/tests/test-signal.lua000066400000000000000000000017411274770366500166100ustar00rootroot00000000000000local child_code = string.dump(function () local uv = require('luv') local signal = uv.new_signal() uv.ref(signal) uv.signal_start(signal, "sigint", function () uv.unref(signal) end) uv.run() os.exit(7) end) return require('lib/tap')(function (test) if _G.isWindows then return end test("Catch SIGINT", function (print, p, expect, uv) local child, pid local input = uv.new_pipe(false) child, pid = assert(uv.spawn(uv.exepath(), { args = {"-"}, -- cwd = uv.cwd(), stdio = {input,1,2} }, expect(function (code, signal) p("exit", {pid=pid,code=code,signal=signal}) assert(code == 7) assert(signal == 0) uv.close(input) uv.close(child) end))) uv.write(input, child_code) uv.shutdown(input) local timer = uv.new_timer() uv.timer_start(timer, 200, 0, expect(function () print("Sending child SIGINT") uv.process_kill(child, "sigint") uv.close(timer) end)) end) end) luv-1.9.1-0/tests/test-tcp.lua000066400000000000000000000070171274770366500161230ustar00rootroot00000000000000return require('lib/tap')(function (test) test("basic tcp server and client", function (print, p, expect, uv) local server = uv.new_tcp() uv.tcp_bind(server, "::", 0) uv.listen(server, 128, expect(function (err) p("server on connection", server) assert(not err, err) uv.close(server) end)) local address = uv.tcp_getsockname(server) p{server=server,address=address} local client = uv.new_tcp() local req = uv.tcp_connect(client, "::1", address.port, expect(function (err) p("client on connect", client, err) assert(not err, err) uv.shutdown(client, expect(function (err) p("client on shutdown", client, err) assert(not err, err) uv.close(client, expect(function () p("client on close", client) end)) end)) end)) p{client=client,req=req} end) test("tcp echo server and client", function (print, p, expect, uv) local server = uv.new_tcp() assert(uv.tcp_bind(server, "127.0.0.1", 0)) assert(uv.listen(server, 1, expect(function () local client = uv.new_tcp() assert(uv.accept(server, client)) assert(uv.read_start(client, expect(function (err, data) p("server read", {err=err,data=data}) assert(not err, err) if data then assert(uv.write(client, data)) else assert(uv.read_stop(client)) uv.close(client) uv.close(server) end end, 2))) end))) local address = uv.tcp_getsockname(server) p{server=server,address=address} local socket = assert(uv.new_tcp()) assert(uv.tcp_connect(socket, "127.0.0.1", address.port, expect(function () assert(uv.read_start(socket, expect(function (err, data) p("client read", {err=err,data=data}) assert(not err, err) assert(uv.read_stop(socket)) uv.close(socket) end))) local req = assert(uv.write(socket, "Hello", function (err) p("client onwrite", socket, err) assert(not err, err) end)) p{socket=socket,req=req} end))) end) test("tcp echo server and client with methods", function (print, p, expect, uv) local server = uv.new_tcp() assert(server:bind("127.0.0.1", 0)) assert(server:listen(1, expect(function () local client = uv.new_tcp() assert(server:accept(client)) assert(client:read_start(expect(function (err, data) p("server read", {err=err,data=data}) assert(not err, err) if data then assert(client:write(data)) else assert(client:read_stop()) client:close() server:close() end end, 2))) end))) local address = server:getsockname() p{server=server,address=address} local socket = assert(uv.new_tcp()) assert(socket:connect("127.0.0.1", address.port, expect(function () assert(socket:read_start(expect(function (err, data) p("client read", {err=err,data=data}) assert(not err, err) assert(socket:read_stop()) socket:close() end))) local req = assert(socket:write("Hello", function (err) p("client onwrite", socket, err) assert(not err, err) end)) p{socket=socket,req=req} end))) end) test("tcp invalid ip address", function (print, p, expect, uv) local ip = '127.0.0.100005' local server = uv.new_tcp() local status, err = pcall(function() uv.tcp_bind(server, ip, 1000) end) assert(not status) p(err) assert(err:find(ip)) uv.close(server) end) end) luv-1.9.1-0/tests/test-thread.lua000066400000000000000000000026221274770366500166010ustar00rootroot00000000000000return require('lib/tap')(function (test) test("test thread create", function(print, p, expect, uv) local delay = 1000 local before = os.time() local thread = uv.new_thread(function(delay) require('luv').sleep(delay) end,delay) uv.thread_join(thread) local elapsed = (os.time() - before) * 1000 p({ delay = delay, elapsed = elapsed }) assert(elapsed >= delay, "elapsed should be at least delay ") end) test("test thread create with arguments", function(print, p, expect, uv) local before = os.time() local args = {500, 'string', nil, false, 5, "helloworld"} local unpack = unpack or table.unpack uv.new_thread(function(num,s,null,bool,five,hw) assert(type(num) == "number") assert(type(s) == "string") assert(null == nil) assert(bool == false) assert(five == 5) assert(hw == 'helloworld') require('luv').sleep(1000) end, unpack(args)):join() local elapsed = (os.time() - before) * 1000 assert(elapsed >= 1000, "elapsed should be at least delay ") end) test("test thread sleep msecs in main thread", function(print, p, expect, uv) local delay = 1000 local before = os.time() uv.sleep(delay) local elapsed = (os.time() - before) * 1000 p({ delay = delay, elapsed = elapsed }) assert(elapsed >= delay, "elapsed should be at least delay ") end) end) luv-1.9.1-0/tests/test-timer.lua000066400000000000000000000046201274770366500164520ustar00rootroot00000000000000return require('lib/tap')(function (test) -- This tests using timers for a simple timeout. -- It also tests the handle close callback and test("simple timeout", function (print, p, expect, uv) local timer = uv.new_timer() local function onclose() p("closed", timer) end local function ontimeout() p("timeout", timer) uv.close(timer, expect(onclose)) end uv.timer_start(timer, 10, 0, expect(ontimeout)) end) -- This is like the previous test, but using repeat. test("simple interval", function (print, p, expect, uv) local timer = uv.new_timer() local count = 3 local onclose = expect(function () p("closed", timer) end) local function oninterval() p("interval", timer) count = count - 1 if count == 0 then uv.close(timer, onclose) end end uv.timer_start(timer, 10, 10, oninterval) end) -- Test two concurrent timers -- There is a small race condition, but there are 100ms of wiggle room. -- 400ms is halfway between 100+200ms and 100+400ms test("timeout with interval", function (print, p, expect, uv) local a = uv.new_timer() local b = uv.new_timer() uv.timer_start(a, 400, 0, expect(function () p("timeout", a) uv.timer_stop(b) uv.close(a) uv.close(b) end)) uv.timer_start(b, 100, 200, expect(function () p("interval", b) end, 2)) end) -- This advanced test uses the rest of the uv_timer_t functions -- to create an interval that shrinks over time. test("shrinking interval", function (print, p, expect, uv) local timer = uv.new_timer() uv.timer_start(timer, 10, 0, expect(function () local r = uv.timer_get_repeat(timer) p("interval", timer, r) if r == 0 then uv.timer_set_repeat(timer, 8) uv.timer_again(timer) elseif r == 2 then uv.timer_stop(timer) uv.close(timer) else uv.timer_set_repeat(timer, r / 2) end end, 4)) end) test("shrinking interval using methods", function (print, p, expect, uv) local timer = uv.new_timer() timer:start(10, 0, expect(function () local r = timer:get_repeat() p("interval", timer, r) if r == 0 then timer:set_repeat(8) timer:again() elseif r == 2 then timer:stop() timer:close() else timer:set_repeat(r / 2) end end, 4)) end) end) luv-1.9.1-0/tests/test-work.lua000066400000000000000000000027021274770366500163130ustar00rootroot00000000000000return require('lib/tap')(function (test) test("test threadpool", function(print,p,expect,_uv) p('Please be patient, the test cost a lots of time') local count = 1000 --for memleaks dected local step = 0 local ctx ctx = _uv.new_work( function(n,s) --work,in threadpool local uv = require('luv') local t = uv.thread_self() uv.sleep(100) return n,n*n, tostring(uv.thread_self()),s end, function(n,r,id, s) assert(n*n==r) if step < count then _uv.queue_work(ctx,n,s) step = step + 1 if (step % 100==0) then p(string.format('run %d%%', math.floor(step*100/count))) end end end --after work, in loop thread ) local ls = string.rep('-',4096) _uv.queue_work(ctx,2,ls) _uv.queue_work(ctx,4,ls) _uv.queue_work(ctx,6,ls) _uv.queue_work(ctx,-2,ls) _uv.queue_work(ctx,-11,ls) _uv.queue_work(ctx,2,ls) _uv.queue_work(ctx,4,ls) _uv.queue_work(ctx,6,ls) _uv.queue_work(ctx,-2,ls) _uv.queue_work(ctx,-11,ls) _uv.queue_work(ctx,2,ls) _uv.queue_work(ctx,4,ls) _uv.queue_work(ctx,6,ls) _uv.queue_work(ctx,-2,ls) _uv.queue_work(ctx,-11,ls) _uv.queue_work(ctx,2,ls) _uv.queue_work(ctx,4,ls) _uv.queue_work(ctx,6,ls) _uv.queue_work(ctx,-2,ls) _uv.queue_work(ctx,-11,ls) end) end)