
The commit adds pathnames to modula-2 which in turn appears in any external symbol. This is necessary to allow different dialects of libraries to coexist (different implementations of SYSTEM and Storage for example in libm2pim and libm2iso). It also makes it easier to debug as the library name forms part of the external mangled name. By default pathnames are not user facing. This commit fixes PR108261. gcc/ChangeLog: PR modula2/108261 * doc/gm2.texi (-fm2-pathname): New option documented. (-fm2-pathnameI): New option documented. (-fm2-prefix=): New option documented. (-fruntime-modules=): Update default module list. gcc/m2/ChangeLog: PR modula2/108261 * Make-lang.in (GM2-COMP-BOOT-DEFS): DynamicStringPath.def remove. DynamicPath.def add. (GM2-COMP-BOOT-MODS): DynamicStringPath.mod remove. DynamicPath.mod add. * Make-maintainer.in (BUILD-BOOT-PPG-H): New dependency. (m2/gm2-ppg-boot/$(SRC_PREFIX)%.o): $(BUILD-BOOT-PPG-H) Add dependency. (PGE-DEF): New definition. (BUILD-BOOT-PG-H): New dependency. (m2/gm2-pg-boot/$(SRC_PREFIX)%.o): $(BUILD-BOOT-PG-H) Add dependency. (BUILD-BOOT-PGE-H): New dependency. (m2/gm2-pge-boot/$(SRC_PREFIX)%.o): $(BUILD-BOOT-PGE-H) Add dependency. (GM2PATH): Add pathname entries. (m2/boot-bin/mc-devel$(exeext)): Add m2/mc-boot-ch/Gm2rtsdummy.o dependency. (m2/boot-bin/mc-opt$(exeext)): Fix -I path. * gm2-compiler/DynamicStringPath.def: Renamed module to DynamicPath. (GetUserPath): Remove. (GetSystemPath): Remove. (SetUserPath): Remove. (SetSystemPath): Remove. (DumpPath): New procedure definition. * gm2-compiler/DynamicStringPath.mod: Renamed module to DynamicPath. (GetUserPath): Remove. (GetSystemPath): Remove. (SetUserPath): Remove. (SetSystemPath): Remove. (DumpPath): Remove Debugging conditional. * gm2-compiler/M2AsmUtil.mod: Import EqualArray, NulName and GetLibName. (Debugging): New declaration. (GetFullSymName): Re-implemented to prefix (mange) libname to any extern variable/procedure which is IsExportQualified. * gm2-compiler/M2Comp.mod (qprintLibName): New procedure. * gm2-compiler/M2Graph.mod (resolveImports): Add libname. * gm2-compiler/M2Options.def (SetM2Prefix): New procedure. (GetM2Prefix): New procedure function. (SetM2PathName): New procedure. (GetM2PathName): New procedure function. * gm2-compiler/M2Options.mod: (SetM2Prefix): New procedure implemented. (GetM2Prefix): New procedure function implemented. (SetM2PathName): New procedure implemented. (GetM2PathName): New procedure function implemented. (RuntimeModuleOverride): Set to DefaultRuntimeModuleOverride. * gm2-compiler/M2Quads.mod: Import GetLibName. (SafeRequestSym) Pass result of GetLibName to RequestDependant. (callRequestDependant): Add libname as a parameter. (BuildM2InitFunction): Add libname as a parameter. (BuildM2FiniFunction): Add libname as a parameter. (BuildM2CtorFunction): Add libname as a parameter. * gm2-compiler/M2Scaffold.mod (LookupModuleSym): Set LibName if a definition source was found. * gm2-compiler/M2Search.def (FindSourceFile): Add named library parameter. (FindSourceDefFile): Add named library parameter. (FindSourceModFile): Add named library parameter. * gm2-compiler/M2Search.mod (FindSourceFile): Reimplement. (FindSourceDefFile): Add named library parameter. (FindSourceModFile): Add named library parameter. * gm2-compiler/SymbolTable.def (MakeProcedureCtorExtern): Add libname parameter. (PutLibName): New procedure. (GetLibName): New procedure function. * gm2-compiler/SymbolTable.mod (MakeProcedureCtorExtern): Add libname parameter. (GenName): Add libname parameter. (InitCtorFields): Add moduleSym as a parameter. (PutCtorExtern): Add libname parameter to GenName. * gm2-gcc/init.cc (_M2_DynamicStringPath_init): Rename function... (_M2_DynamicPath_init): ...to this. (_M2_PathName_init): Added. * gm2-gcc/m2decl.cc (m2decl_DeclareM2linkStaticInitialization): Add m2pim as the manged component of the exported symbol. (m2decl_DeclareM2linkForcedModuleInitOrder): Add m2pim mangle prefix. * gm2-gcc/m2options.h (M2Options_SetM2Prefix): New function. (M2Options_GetM2Prefix): New function. (M2Options_SetM2PathName): New function. (M2Options_GetM2PathName): New function. * gm2-lang.cc (push_back_Ipath): New function. (add_one_import_path): New function. (gm2_langhook_handle_option): Record -I component. Call SetM2PathName when -fm2-pathname= is seen. Record -fm2-pathnameI component. Call SetM2Prefix when -fm2-prefix= is seen. (gm2_langhook_post_options): Iterative over pathname entries and call SetM2PathName, SetSearchPath as appropriate. * gm2-libs-iso/M2RTS.def (ConstructModules): Add libname parameter. (DeconstructModules): Add libname parameter. (RegisterModule): Add libname parameter. (RequestDependant): Add libname parameter. * gm2-libs-iso/M2RTS.mod (ConstructModules): Add libname parameter. (DeconstructModules): Add libname parameter. (RegisterModule): Add libname parameter. (RequestDependant): Add libname parameter. * gm2-libs-min/M2RTS.def (ConstructModules): Add libname parameter. (DeconstructModules): Add libname parameter. (RegisterModule): Add libname parameter. (RequestDependant): Add libname parameter. * gm2-libs-min/M2RTS.mod (ConstructModules): Add libname parameter. (DeconstructModules): Add libname parameter. (RegisterModule): Add libname parameter. (RequestDependant): Add libname parameter. * gm2-libs/M2Dependent.def (ConstructModules): Add libname parameter. (DeconstructModules): Add libname parameter. (RegisterModule): Add libname parameter. (RequestDependant): Add libname parameter. * gm2-libs/M2Dependent.mod (ConstructModules): Add libname parameter. (DeconstructModules): Add libname parameter. (RegisterModule): Add libname parameter. (RequestDependant): Add libname parameter. * gm2-libs/M2RTS.def (ConstructModules): Add libname parameter. (DeconstructModules): Add libname parameter. (RegisterModule): Add libname parameter. (RequestDependant): Add libname parameter. * gm2-libs/M2RTS.mod (ConstructModules): Add libname parameter. (DeconstructModules): Add libname parameter. (RegisterModule): Add libname parameter. (RequestDependant): Add libname parameter. * gm2-libs/RTint.mod (FindVector): Rename variables. (initInputVector): Rename variables. (initOutputVector): Rename variables. (InitTimeVector): Rename variables. (FindVectorNo): Rename variables. (FindPendingVector): Rename variables. (ReArmTimeVector): Rename variables. (GetTimeVector): Rename variables. (AttachVector): Rename variables. (AttachVector): Rename variables. (IncludeVector): Rename variables. (ExcludeVector): Rename variables. (AddFd): Rename variables. (AddFd): Rename variables. (DumpPendingQueue): Rename variables. (stop): Remove. (activatePending): Rename variables. (Listen): Rename variables. * gm2-libs/libc.def (snprintf): New function. * gm2-libs/sckt.def: Change all exported identifiers to be export qualified. * gm2spec.cc (push_back_Ipath): New function. (add_m2_I_path): New function. (lang_specific_driver): Skip -fm2-pathname= and remember pathname. Skip -I and record the path and current pathname. Call add_m2_I_path. * lang-specs.h: Replace %{I*} with %{fm2-pathname*}. * lang.opt (-fm2-pathname=): New entry. (-fm2-pathname): New entry. (-fm2-prefix=): New entry. * mc-boot-ch/GUnixArgs.cc (_M2_UnixArgs_dep): New function. (_M2_UnixArgs_ctor::_M2_UnixArgs_ctor): New method. * mc-boot-ch/Glibc.c (libc_snprintf): New function. * mc-boot-ch/m2rts.h (M2RTS_RequestDependant): Changed prototype. (M2RTS_RegisterModule): Changed prototype. * mc-boot/GDynamicStrings.c: Rebuild. * mc-boot/GFIO.c: Rebuild. * mc-boot/GIndexing.c: Rebuild. * mc-boot/GM2Dependent.c: Rebuild. * mc-boot/GM2Dependent.h: Rebuild. * mc-boot/GM2EXCEPTION.c: Rebuild. * mc-boot/GM2RTS.c: Rebuild. * mc-boot/GM2RTS.h: Rebuild. * mc-boot/GPushBackInput.c: Rebuild. * mc-boot/GRTExceptions.c: Rebuild. * mc-boot/GRTint.c: Rebuild. * mc-boot/GStdIO.c: Rebuild. * mc-boot/GStringConvert.c: Rebuild. * mc-boot/GSysStorage.c: Rebuild. * mc-boot/Gdecl.c: Rebuild. * mc-boot/Gkeyc.c: Rebuild. * mc-boot/Glibc.h: Rebuild. * mc-boot/GmcComment.c: Rebuild. * mc-boot/GmcComp.c: Rebuild. * mc-boot/GmcDebug.c: Rebuild. * mc-boot/GmcMetaError.c: Rebuild. * mc-boot/GmcStack.c: Rebuild. * mc-boot/GnameKey.c: Rebuild. * mc-boot/GsymbolKey.c: Rebuild. * pge-boot/GASCII.c: Rebuild. * pge-boot/GArgs.c: Rebuild. * pge-boot/GAssertion.c: Rebuild. * pge-boot/GDebug.c: Rebuild. * pge-boot/GDynamicStrings.c: Rebuild. * pge-boot/GFIO.c: Rebuild. * pge-boot/GIO.c: Rebuild. * pge-boot/GIndexing.c: Rebuild. * pge-boot/GLists.c: Rebuild. * pge-boot/GM2Dependent.c: Rebuild. * pge-boot/GM2Dependent.h: Rebuild. * pge-boot/GM2EXCEPTION.c: Rebuild. * pge-boot/GM2RTS.c: Rebuild. * pge-boot/GM2RTS.h: Rebuild. * pge-boot/GNameKey.c: Rebuild. * pge-boot/GNumberIO.c: Rebuild. * pge-boot/GOutput.c: Rebuild. * pge-boot/GPushBackInput.c: Rebuild. * pge-boot/GRTExceptions.c: Rebuild. * pge-boot/GSFIO.c: Rebuild. * pge-boot/GStdIO.c: Rebuild. * pge-boot/GStorage.c: Rebuild. * pge-boot/GStrCase.c: Rebuild. * pge-boot/GStrIO.c: Rebuild. * pge-boot/GStrLib.c: Rebuild. * pge-boot/GSymbolKey.c: Rebuild. * pge-boot/GSysExceptions.c (_M2_SysExceptions_finish): Rename this... (_M2_SysExceptions_fini): ... to this. * pge-boot/GSysStorage.c: Rebuild. (_M2_SysStorage_finish): Rename this... (_M2_SysStorage_fini): ... to this. * pge-boot/GUnixArgs.cc: New file. * pge-boot/Gbnflex.c (_M2_bnflex_finish): Rename this... (_M2_bnflex_fini): ... to this. * pge-boot/Gerrno.c (_M2_errno_finish): Rename this... (_M2_errno_fini): ... to this. * pge-boot/Glibc.c (libc_snprintf): New function. * pge-boot/Glibc.h (libc_snprintf): New prototype. * pge-boot/Gpge.c (_M2_pge_finish): Rename this... (_M2_pge_fini): ... to this. * pge-boot/Gtermios.cc (_M2_termios_finish): Rename this... (_M2_termios_fini): ... to this. * pge-boot/main.c (_M2_RTExceptions_finish): Rename this... (_M2_RTExceptions_fini): ... to this. (_M2_M2EXCEPTION_finish): Rename this... (_M2_M2EXCEPTION_fini): ... to this. (_M2_M2RTS_finish): Rename this... (_M2_M2RTS_fini): ... to this. (_M2_SysExceptions_finish): Rename this... (_M2_SysExceptions_fini): ... to this. (_M2_StrLib_finish): Rename this... (_M2_StrLib_fini): ... to this. (_M2_errno_finish): Rename this... (_M2_errno_fini): ... to this. (_M2_termios_finish): Rename this... (_M2_termios_fini): ... to this. (_M2_IO_finish): Rename this... (_M2_IO_fini): ... to this. (_M2_StdIO_finish): Rename this... (_M2_StdIO_fini): ... to this. (_M2_Debug_finish): Rename this... (_M2_Debug_fini): ... to this. (_M2_SysStorage_finish): Rename this... (_M2_SysStorage_fini): ... to this. (_M2_Storage_finish): Rename this... (_M2_Storage_fini): ... to this. (_M2_StrIO_finish): Rename this... (_M2_StrIO_fini): ... to this. (_M2_DynamicStrings_finish): Rename this... (_M2_DynamicStrings_fini): ... to this. (_M2_Assertion_finish): Rename this... (_M2_Assertion_fini): ... to this. (_M2_Indexing_finish): Rename this... (_M2_Indexing_fini): ... to this. (_M2_NameKey_finish): Rename this... (_M2_NameKey_fini): ... to this. (_M2_NumberIO_finish): Rename this... (_M2_NumberIO_fini): ... to this. (_M2_PushBackInput_finish): Rename this... (_M2_PushBackInput_fini): ... to this. (_M2_SymbolKey_finish): Rename this... (_M2_SymbolKey_fini): ... to this. (_M2_UnixArgs_finish): Rename this... (_M2_UnixArgs_fini): ... to this. (_M2_FIO_finish): Rename this... (_M2_FIO_fini): ... to this. (_M2_SFIO_finish): Rename this... (_M2_SFIO_fini): ... to this. (_M2_StrCase_finish): Rename this... (_M2_StrCase_fini): ... to this. (_M2_bnflex_finish): Rename this... (_M2_bnflex_fini): ... to this. (_M2_Lists_finish): Rename this... (_M2_Lists_fini): ... to this. (_M2_Args_finish): Rename this... (_M2_Args_fini): ... to this. (_M2_Output_finish): Rename this... (_M2_Output_fini): ... to this. (_M2_pge_finish): Rename this... (_M2_pge_fini): ... to this. * plugin/m2rte.cc (m2_runtime_error_calls): Change all runtime procedure names to their name mangled counterparts. * gm2-libs-iso/wrapsock.c: Removed. * gm2-libs-iso/wraptime.c: Removed. * mc-boot/Gpth.h: Removed. * gm2-compiler/PathName.def: New file. * gm2-compiler/PathName.mod: New file. libgm2/ChangeLog: PR modula2/108261 * libm2cor/KeyBoardLEDs.cc (EXPORT): New define. (M2EXPORT): New define. (M2LIBNAME): New define. (KeyBoardLEDs_SwitchScroll): EXPORT. (KeyBoardLEDs_SwitchNum): EXPORT. (KeyBoardLEDs_SwitchCaps): EXPORT. (KeyBoardLEDs_SwitchLeds): EXPORT. (_M2_KeyBoardLEDs_init): M2EXPORT. (_M2_KeyBoardLEDs_finish): M2EXPORT. (_M2_KeyBoardLEDs_dep): M2EXPORT. * libm2cor/Makefile.am (libm2cor_la_M2FLAGS): Define path names. * libm2cor/Makefile.in: Rebuild. * libm2iso/ErrnoCategory.cc (EXPORT): New define. (M2EXPORT): New define. (M2LIBNAME): New define. (ErrnoCategory_IsErrnoHard): EXPORT. (ErrnoCategory_IsErrnoSoft): EXPORT. (ErrnoCategory_UnAvailable): EXPORT. (ErrnoCategory_GetOpenResults): EXPORT. (_M2_ErrnoCategory_init): M2EXPORT. (_M2_ErrnoCategory_fini): M2EXPORT. (_M2_ErrnoCategory_dep): M2EXPORT. (_M2_ErrnoCategory_ctor): M2EXPORT. * libm2iso/Makefile.am (libm2iso_la_M2FLAGS): Define path names. * libm2iso/Makefile.in: Rebuild. * libm2iso/RTco.cc (EXPORT): New define. (M2EXPORT): New define. (M2LIBNAME): New define. (newSem): Add module libname prefix to HaltC. (currentThread): Remove variable and replace with a function. (never): Add module libname prefix to HaltC. (initThread): Add module libname prefix to HaltC. * libm2iso/m2rts.h (str): New define. (M2RTS_RequestDependant): Change to the mangled name equivalent. (M2RTS_RegisterModule): Change to the mangled name equivalent. (m2iso_M2RTS_RequestDependant): Add libname parameter. (m2iso_M2RTS_RegisterModule): Add libname parameter. (m2pim_M2RTS_RegisterModule): Add libname parameter. (_M2_M2RTS_init): Rename this... (m2iso_M2_M2RTS_init): ...to this. (M2RTS_ConstructModules): Change to the mangled name equivalent. (M2RTS_Terminate): Change to the mangled name equivalent. (M2RTS_DeconstructModules): Change to the mangled name equivalent. (m2iso_M2RTS_ConstructModules): Add libname parameter. (m2iso_M2RTS_Terminate): Add libname parameter. (m2iso_M2RTS_DeconstructModules): Add libname parameter. (M2RTS_HaltC): Rename this... (m2iso_M2RTS_HaltC): ...to this. * libm2iso/wrapsock.c (EXPORT): New define. (IMPORT): New define. (M2EXPORT): New define. (M2LIBNAME): New define. (m2iso_M2RTS_RequestDependant): Add prototype. (wrapsock_clientOpen): EXPORT. (wrapsock_clientOpenIP): EXPORT. (wrapsock_getClientPortNo): EXPORT. (wrapsock_getClientHostname): EXPORT. (wrapsock_getClientSocketFd): EXPORT. (wrapsock_getClientIP): EXPORT. (wrapsock_getPushBackChar): EXPORT. (wrapsock_setPushBackChar): EXPORT. (wrapsock_getSizeOfClientInfo): EXPORT. (_M2_wrapsock_init): M2EXPORT. (_M2_wrapsock_fini): M2EXPORT. (ctor): M2EXPORT. New function. * libm2iso/wraptime.c: Rename to... * libm2iso/wraptime.cc: ...this. (EXPORT): New define. (M2EXPORT): New define. (M2LIBNAME): New define. (wraptime_InitTimeval): EXPORT. (wraptime_KillTimeval): EXPORT. (wraptime_InitTimezone): EXPORT. (wraptime_KillTimezone): EXPORT. (wraptime_InitTM): EXPORT. (wraptime_KillTM): EXPORT. (wraptime_gettimeofday): EXPORT. (wraptime_settimeofday): EXPORT. (wraptime_GetFractions): EXPORT. (wraptime_localtime_r): EXPORT. (wraptime_GetYear): EXPORT. (wraptime_GetMonth): EXPORT. (wraptime_GetDay): EXPORT. (wraptime_GetHour): EXPORT. (wraptime_GetMinute): EXPORT. (wraptime_GetSecond): EXPORT. (wraptime_GetSummerTime): EXPORT. (wraptime_GetDST): EXPORT. (wraptime_SetTimezone): EXPORT. (wraptime_SetTimeval): EXPORT. (_M2_wraptime_init): M2EXPORT. (_M2_wraptime_fini): M2EXPORT. (ctor): M2EXPORT. New function. * libm2log/Makefile.am (libm2log_la_M2FLAGS): Define path names. * libm2log/Makefile.in: * libm2min/Makefile.am (libm2min_la_M2FLAGS): Define path names. * libm2min/Makefile.in: * libm2pim/Makefile.am (libm2pim_la_M2FLAGS): Define path names. * libm2pim/Makefile.in: * libm2pim/Selective.cc (EXPORT): New define. (M2EXPORT): New define. (M2LIBNAME): New define. (Selective_Select): EXPORT. (Selective_InitTime): EXPORT. (Selective_GetTime): EXPORT. (Selective_SetTime): EXPORT. (Selective_KillTime): EXPORT. (Selective_InitSet): EXPORT. (Selective_KillSet): EXPORT. (Selective_FdZero): EXPORT. (Selective_FdSet): EXPORT. (Selective_FdClr): EXPORT. (Selective_FdIsSet): EXPORT. (Selective_GetTimeOfDay): EXPORT. (Selective_MaxFdsPlusOne): EXPORT. (Selective_WriteCharRaw): EXPORT. (Selective_ReadCharRaw): EXPORT. (_M2_Selective_init): M2EXPORT. (_M2_Selective_fini): M2EXPORT. (_M2_Selective_dep): M2EXPORT. (_M2_Selective_ctor): M2EXPORT. * libm2pim/SysExceptions.cc (EXPORT): New define. (M2EXPORT): New define. (M2LIBNAME): New define. (SysExceptions_InitExceptionHandlers): EXPORT. (_M2_SysExceptions_init): M2EXPORT. (_M2_SysExceptions_fini): M2EXPORT. (_M2_SysExceptions_dep): M2EXPORT. (_M2_SysExceptions_ctor): M2EXPORT. * libm2pim/UnixArgs.cc (EXPORT): New define. (M2EXPORT): New define. (M2LIBNAME): New define. (UnixArgs_GetArgC): EXPORT. (UnixArgs_GetArgV): EXPORT. (UnixArgs_GetEnvV): EXPORT. (_M2_UnixArgs_init): M2EXPORT. (_M2_UnixArgs_fini): M2EXPORT. (_M2_UnixArgs_dep): M2EXPORT. (_M2_UnixArgs_ctor): M2EXPORT. * libm2pim/cgetopt.cc (EXPORT): New define. (M2EXPORT): New define. (M2LIBNAME): New define. (cgetopt_getopt): EXPORT. (cgetopt_getopt_long): EXPORT. (cgetopt_getopt_long_only): EXPORT. (cgetopt_InitOptions): EXPORT. (cgetopt_KillOptions): EXPORT. (cgetopt_SetOption): EXPORT. (cgetopt_GetLongOptionArray): EXPORT. (_M2_cgetopt_init): M2EXPORT. (_M2_cgetopt_fini): M2EXPORT. (_M2_cgetopt_dep): M2EXPORT. (_M2_cgetopt_ctor): M2EXPORT. * libm2pim/dtoa.cc (EXPORT): New define. (M2EXPORT): New define. (M2LIBNAME): New define. (dtoa_strtod): EXPORT. (dtoa_calcmaxsig): EXPORT. (dtoa_calcdecimal): EXPORT. (dtoa_calcsign): EXPORT. (dtoa_dtoa): EXPORT. (_M2_dtoa_init): M2EXPORT. (_M2_dtoa_fini): M2EXPORT. (_M2_dtoa_dep): M2EXPORT. (_M2_dtoa_ctor): M2EXPORT. * libm2pim/errno.cc (EXPORT): New define. (M2EXPORT): New define. (M2LIBNAME): New define. (errno_geterrno): EXPORT. (_M2_errno_init): M2EXPORT. (_M2_errno_fini): M2EXPORT. (_M2_errno_dep): M2EXPORT. (_M2_errno_ctor): M2EXPORT. * libm2pim/ldtoa.cc (EXPORT): New define. (IMPORT): New define. (M2EXPORT): New define. (M2LIBNAME): New define. (dtoa_calcmaxsig): EXPORT. (dtoa_calcdecimal): EXPORT. (dtoa_calcsign): EXPORT. (ldtoa_strtold): EXPORT. (ldtoa_ldtoa): EXPORT. (_M2_ldtoa_init): M2EXPORT. (_M2_ldtoa_fini): M2EXPORT. (_M2_ldtoa_dep): M2EXPORT. (_M2_ldtoa_ctor): M2EXPORT. * libm2pim/sckt.cc (EXPORT): New define. (M2EXPORT): New define. (M2LIBNAME): New define. (tcpServerEstablishPort): EXPORT. (tcpServerEstablish): EXPORT. (tcpServerAccept): EXPORT. (tcpServerPortNo): EXPORT. (tcpServerSocketFd): EXPORT. (getLocalIP): EXPORT. (tcpServerIP): EXPORT. (tcpServerClientIP): EXPORT. (tcpServerClientPortNo): EXPORT. (tcpClientSocket): EXPORT. (tcpClientSocketIP): EXPORT. (tcpClientConnect): EXPORT. (tcpClientPortNo): EXPORT. (tcpClientSocketFd): EXPORT. (tcpClientIP): EXPORT. (_M2_sckt_init): M2EXPORT. (_M2_sckt_finish): M2EXPORT. (_M2_sckt_dep): M2EXPORT. (_M2_sckt_ctor): M2EXPORT. * libm2pim/termios.cc (EXPORT): New define. (M2EXPORT): New define. (M2LIBNAME): New define. (_M2_termios_init): M2EXPORT. (_M2_termios_fini): M2EXPORT. (_M2_termios_dep): M2EXPORT. (_M2_termios_ctor): M2EXPORT. * libm2pim/wrapc.c (EXPORT): New define. (M2EXPORT): New define. (M2LIBNAME): New define. (wrapc_strtime): EXPORT. (wrapc_filesize): EXPORT. (wrapc_filemtime): EXPORT. (wrapc_fileinode): EXPORT. (wrapc_getrand): EXPORT. (wrapc_getusername): EXPORT. (wrapc_getnameuidgid): EXPORT. (wrapc_signbit): EXPORT. (wrapc_signbitl): EXPORT. (wrapc_signbitf): EXPORT. (wrapc_isfinite): EXPORT. (wrapc_isfinitel): EXPORT. (wrapc_isfinitef): EXPORT. (_M2_wrapc_init): M2EXPORT. (_M2_wrapc_fini): M2EXPORT. (_M2_wrapc_ctor): M2EXPORT. gcc/testsuite/ChangeLog: PR modula2/108261 * gm2/examples/callingC/pass/examples-callingC-pass.exp: Tidy up variable access. * gm2/examples/callingC/run/pass/examples-callingC-run-pass.exp: Tidy up variable access. * gm2/examples/cpp/pass/examples-cpp-pass.exp: Tidy up variable access. * gm2/examples/cppDef/pass/examples-cppDef-pass.exp: Tidy up variable access. * gm2/examples/hello/pass/examples-hello-pass.exp: Tidy up variable access. * gm2/examples/map/pass/examples-map-pass.exp: Tidy up variable access. * gm2/iso/check/fail/iso-check-fail.exp: Add pathname. * gm2/link/externalscaffold/pass/link-externalscaffold-pass.exp: Add pathname. * gm2/link/externalscaffold/pass/scaffold.c: Add mangled export name. * gm2/pimlib/base/run/pass/FIO.mod: Updated test code. * gm2/pimlib/base/run/pass/StrLib.mod: Updated test code. * gm2/pimlib/base/run/pass/pimlib-base-run-pass.exp: Remove path. * gm2/projects/pim/run/pass/random/projects-pim-run-pass-random.exp: Tidy up variable access. * gm2/switches/auto-init/fail/switches-auto-init-fail.exp: Add pathname. * gm2/switches/check-all/pim2/fail/switches-check-all-pim2-fail.exp: Add pathname. * gm2/switches/makeall/fail/switches-makeall-fail.exp: Remove -fmakeall. * gm2/switches/makeall/pass/switches-makeall-pass.exp: Remove -fmakeall. * lib/gm2-simple.exp (gm2_keep_executable): New global variable. (gm2_simple_execute): Keep executable if global is true. * lib/gm2-torture.exp: Add ; after global variable access. * lib/gm2.exp: Set up pathnames. * gm2/projects/pim/run/pass/tower/AdvCmd.def: New test. * gm2/projects/pim/run/pass/tower/AdvCmd.mod: New test. * gm2/projects/pim/run/pass/tower/AdvIntroduction.def: New test. * gm2/projects/pim/run/pass/tower/AdvIntroduction.mod: New test. * gm2/projects/pim/run/pass/tower/AdvMap.def: New test. * gm2/projects/pim/run/pass/tower/AdvMap.mod: New test. * gm2/projects/pim/run/pass/tower/AdvMath.def: New test. * gm2/projects/pim/run/pass/tower/AdvMath.mod: New test. * gm2/projects/pim/run/pass/tower/AdvParse.bnf: New test. * gm2/projects/pim/run/pass/tower/AdvParse.def: New test. * gm2/projects/pim/run/pass/tower/AdvParse.mod: New test. * gm2/projects/pim/run/pass/tower/AdvSound.def: New test. * gm2/projects/pim/run/pass/tower/AdvSound.mod: New test. * gm2/projects/pim/run/pass/tower/AdvSystem.def: New test. * gm2/projects/pim/run/pass/tower/AdvSystem.mod: New test. * gm2/projects/pim/run/pass/tower/AdvTreasure.def: New test. * gm2/projects/pim/run/pass/tower/AdvTreasure.mod: New test. * gm2/projects/pim/run/pass/tower/AdvUtil.def: New test. * gm2/projects/pim/run/pass/tower/AdvUtil.mod: New test. * gm2/projects/pim/run/pass/tower/DrawG.def: New test. * gm2/projects/pim/run/pass/tower/DrawG.mod: New test. * gm2/projects/pim/run/pass/tower/DrawL.def: New test. * gm2/projects/pim/run/pass/tower/DrawL.mod: New test. * gm2/projects/pim/run/pass/tower/Dungeon.mod: New test. * gm2/projects/pim/run/pass/tower/Lock.def: New test. * gm2/projects/pim/run/pass/tower/Lock.mod: New test. * gm2/projects/pim/run/pass/tower/ProcArgs.def: New test. * gm2/projects/pim/run/pass/tower/ProcArgs.mod: New test. * gm2/projects/pim/run/pass/tower/Screen.def: New test. * gm2/projects/pim/run/pass/tower/Screen.mod: New test. * gm2/projects/pim/run/pass/tower/SocketControl.c: New test. * gm2/projects/pim/run/pass/tower/SocketControl.def: New test. * gm2/projects/pim/run/pass/tower/Window.def: New test. * gm2/projects/pim/run/pass/tower/Window.mod: New test. * gm2/projects/pim/run/pass/tower/adv.flex: New test. * gm2/projects/pim/run/pass/tower/advflex.c: New test. * gm2/projects/pim/run/pass/tower/advflex.def: New test. * gm2/projects/pim/run/pass/tower/projects-pim-run-pass-tower.exp: New test. * gm2/projects/pim/run/pass/tower/star: New test. Signed-off-by: Gaius Mulley <gaiusmod2@gmail.com>
434 lines
10 KiB
C++
434 lines
10 KiB
C++
/* sckt.c provide access to the socket layer.
|
|
|
|
Copyright (C) 2005-2022 Free Software Foundation, Inc.
|
|
Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
|
|
|
|
This file is part of GNU Modula-2.
|
|
|
|
GNU Modula-2 is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 3, or (at your option)
|
|
any later version.
|
|
|
|
GNU Modula-2 is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
General Public License for more details.
|
|
|
|
Under Section 7 of GPL version 3, you are granted additional
|
|
permissions described in the GCC Runtime Library Exception, version
|
|
3.1, as published by the Free Software Foundation.
|
|
|
|
You should have received a copy of the GNU General Public License and
|
|
a copy of the GCC Runtime Library Exception along with this program;
|
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
<http://www.gnu.org/licenses/>. */
|
|
|
|
#include <config.h>
|
|
#include <m2rts.h>
|
|
|
|
#define EXPORT(FUNC) m2pim ## _sckt_ ## FUNC
|
|
#define M2EXPORT(FUNC) m2pim ## _M2_sckt_ ## FUNC
|
|
#define M2LIBNAME "m2pim"
|
|
|
|
#if defined(HAVE_SYS_TYPES_H)
|
|
#include <sys/types.h>
|
|
#endif
|
|
|
|
#if defined(HAVE_SYS_SOCKET_H)
|
|
#include <sys/socket.h>
|
|
#endif
|
|
|
|
#if defined(HAVE_NETINET_IN_H)
|
|
#include <netinet/in.h>
|
|
#endif
|
|
|
|
#if defined(HAVE_NETDB_H)
|
|
#include <netdb.h>
|
|
#endif
|
|
|
|
#if defined(HAVE_UNISTD_H)
|
|
#include <unistd.h>
|
|
#endif
|
|
|
|
#if defined(HAVE_SIGNAL_H)
|
|
#include <signal.h>
|
|
#endif
|
|
|
|
#if defined(HAVE_SYS_ERRNO_H)
|
|
#include <sys/errno.h>
|
|
#endif
|
|
|
|
#if defined(HAVE_ERRNO_H)
|
|
#include <errno.h>
|
|
#endif
|
|
|
|
#if defined(HAVE_MALLOC_H)
|
|
#include <malloc.h>
|
|
#endif
|
|
|
|
#if defined(HAVE_STRING_H)
|
|
#include <string.h>
|
|
#endif
|
|
|
|
#if defined(HAVE_STDLIB_H)
|
|
#include <stdlib.h>
|
|
#endif
|
|
|
|
#if defined(HAVE_STDIO_H)
|
|
#include <stdio.h>
|
|
#endif
|
|
|
|
#define PORTSTART 7000
|
|
#define NOOFTRIES 100
|
|
#define MAXHOSTNAME 256
|
|
|
|
#undef DEBUGGING
|
|
|
|
#if !defined(TRUE)
|
|
#define TRUE (1 == 1)
|
|
#endif
|
|
#if !defined(FALSE)
|
|
#define FALSE (1 == 0)
|
|
#endif
|
|
|
|
#if defined(HAVE_SYS_SOCKET_H)
|
|
|
|
#define ERROR(X) \
|
|
{ \
|
|
printf ("%s:%d:%s\n", __FILE__, __LINE__, X); \
|
|
localExit (1); \
|
|
}
|
|
|
|
#define ASSERT(X) \
|
|
{ \
|
|
if (!(X)) \
|
|
{ \
|
|
printf ("%s:%d: assert(%s) failed\n", __FILE__, __LINE__, #X); \
|
|
exit (1); \
|
|
} \
|
|
}
|
|
|
|
typedef struct
|
|
{
|
|
char hostname[MAXHOSTNAME];
|
|
struct hostent *hp;
|
|
struct sockaddr_in sa, isa;
|
|
int sockFd;
|
|
int portNo;
|
|
} tcpServerState;
|
|
|
|
int
|
|
localExit (int i)
|
|
{
|
|
exit (1);
|
|
}
|
|
|
|
/* tcpServerEstablishPort returns a tcpState containing the relevant
|
|
information about a socket declared to receive tcp connections.
|
|
This method attempts to use the port specified by the parameter. */
|
|
|
|
extern "C" tcpServerState *
|
|
EXPORT(tcpServerEstablishPort) (int portNo)
|
|
{
|
|
tcpServerState *s = (tcpServerState *)malloc (sizeof (tcpServerState));
|
|
int b, p, n;
|
|
|
|
if (s == NULL)
|
|
ERROR ("no more memory");
|
|
|
|
/* Remove SIGPIPE which is raised on the server if the client is killed. */
|
|
signal (SIGPIPE, SIG_IGN);
|
|
|
|
if (gethostname (s->hostname, MAXHOSTNAME) < 0)
|
|
ERROR ("cannot find our hostname");
|
|
|
|
s->hp = gethostbyname (s->hostname);
|
|
if (s->hp == NULL)
|
|
ERROR ("cannot get host name");
|
|
|
|
p = -1;
|
|
n = 0;
|
|
do
|
|
{
|
|
p++;
|
|
/* Open a TCP socket (an Internet stream socket). */
|
|
|
|
s->sockFd = socket (s->hp->h_addrtype, SOCK_STREAM, 0);
|
|
if (s->sockFd < 0)
|
|
ERROR ("socket");
|
|
|
|
memset ((void *)&s->sa, 0, sizeof (s->sa));
|
|
ASSERT ((s->hp->h_addrtype == AF_INET));
|
|
s->sa.sin_family = s->hp->h_addrtype;
|
|
s->sa.sin_addr.s_addr = htonl (INADDR_ANY);
|
|
s->sa.sin_port = htons (portNo + p);
|
|
|
|
b = bind (s->sockFd, (struct sockaddr *)&s->sa, sizeof (s->sa));
|
|
}
|
|
while ((b < 0) && (n < NOOFTRIES));
|
|
|
|
if (b < 0)
|
|
ERROR ("bind");
|
|
|
|
s->portNo = portNo + p;
|
|
#if defined(DEBUGGING)
|
|
printf ("the receiving host is: %s, the port is %d\n", s->hostname,
|
|
s->portNo);
|
|
#endif
|
|
listen (s->sockFd, 1);
|
|
return s;
|
|
}
|
|
|
|
/* tcpServerEstablish returns a tcpServerState containing the relevant
|
|
information about a socket declared to receive tcp connections. */
|
|
|
|
extern "C" tcpServerState *
|
|
EXPORT(tcpServerEstablish) (void)
|
|
{
|
|
return EXPORT(tcpServerEstablishPort) (PORTSTART);
|
|
}
|
|
|
|
/* tcpServerAccept returns a file descriptor once a client has connected and
|
|
been accepted. */
|
|
|
|
extern "C" int
|
|
EXPORT(tcpServerAccept) (tcpServerState *s)
|
|
{
|
|
socklen_t i = sizeof (s->isa);
|
|
int t;
|
|
|
|
#if defined(DEBUGGING)
|
|
printf ("before accept %d\n", s->sockFd);
|
|
#endif
|
|
t = accept (s->sockFd, (struct sockaddr *)&s->isa, &i);
|
|
return t;
|
|
}
|
|
|
|
/* tcpServerPortNo returns the portNo from structure, s. */
|
|
|
|
extern "C" int
|
|
EXPORT(tcpServerPortNo) (tcpServerState *s)
|
|
{
|
|
return s->portNo;
|
|
}
|
|
|
|
/* tcpServerSocketFd returns the sockFd from structure, s. */
|
|
|
|
extern "C" int
|
|
EXPORT(tcpServerSocketFd) (tcpServerState *s)
|
|
{
|
|
return s->sockFd;
|
|
}
|
|
|
|
/* getLocalIP returns the IP address of this machine. */
|
|
|
|
extern "C" unsigned int
|
|
EXPORT(getLocalIP) (tcpServerState *s)
|
|
{
|
|
char hostname[1024];
|
|
struct hostent *hp;
|
|
struct sockaddr_in sa;
|
|
unsigned int ip;
|
|
int ret = gethostname (hostname, sizeof (hostname));
|
|
|
|
if (ret == -1)
|
|
{
|
|
ERROR ("gethostname");
|
|
return 0;
|
|
}
|
|
|
|
hp = gethostbyname (hostname);
|
|
if (hp == NULL)
|
|
{
|
|
ERROR ("gethostbyname");
|
|
return 0;
|
|
}
|
|
|
|
if (sizeof (unsigned int) != sizeof (in_addr_t))
|
|
{
|
|
ERROR ("bad ip length");
|
|
return 0;
|
|
}
|
|
|
|
memset (&sa, sizeof (struct sockaddr_in), 0);
|
|
sa.sin_family = AF_INET;
|
|
sa.sin_port = htons (80);
|
|
if (hp->h_length == sizeof (unsigned int))
|
|
{
|
|
memcpy (&ip, hp->h_addr_list[0], hp->h_length);
|
|
return ip;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* tcpServerIP returns the IP address from structure s. */
|
|
|
|
extern "C" int
|
|
EXPORT(tcpServerIP) (tcpServerState *s)
|
|
{
|
|
return *((int *)s->hp->h_addr_list[0]);
|
|
}
|
|
|
|
/* tcpServerClientIP returns the IP address of the client who
|
|
has connected to server s. */
|
|
|
|
extern "C" unsigned int
|
|
EXPORT(tcpServerClientIP) (tcpServerState *s)
|
|
{
|
|
unsigned int ip;
|
|
|
|
ASSERT (s->isa.sin_family == AF_INET);
|
|
ASSERT (sizeof (ip) == 4);
|
|
memcpy (&ip, &s->isa.sin_addr, sizeof (ip));
|
|
return ip;
|
|
}
|
|
|
|
/* tcpServerClientPortNo returns the port number of the client who
|
|
has connected to server s. */
|
|
|
|
extern "C" unsigned int
|
|
EXPORT(tcpServerClientPortNo) (tcpServerState *s)
|
|
{
|
|
return s->isa.sin_port;
|
|
}
|
|
|
|
/*
|
|
****************************************************************
|
|
*** C L I E N T R O U T I N E S
|
|
****************************************************************
|
|
*/
|
|
|
|
typedef struct
|
|
{
|
|
char hostname[MAXHOSTNAME];
|
|
struct hostent *hp;
|
|
struct sockaddr_in sa;
|
|
int sockFd;
|
|
int portNo;
|
|
} tcpClientState;
|
|
|
|
/* tcpClientSocket returns a file descriptor (socket) which has
|
|
connected to, serverName:portNo. */
|
|
|
|
extern "C" tcpClientState *
|
|
EXPORT(tcpClientSocket) (char *serverName, int portNo)
|
|
{
|
|
tcpClientState *s = (tcpClientState *)malloc (sizeof (tcpClientState));
|
|
|
|
if (s == NULL)
|
|
ERROR ("no more memory");
|
|
|
|
/* Remove SIGPIPE which is raised on the server if the client is killed. */
|
|
signal (SIGPIPE, SIG_IGN);
|
|
|
|
s->hp = gethostbyname (serverName);
|
|
if (s->hp == NULL)
|
|
{
|
|
fprintf (stderr, "cannot find host: %s\n", serverName);
|
|
exit (1);
|
|
}
|
|
|
|
memset ((void *)&s->sa, 0, sizeof (s->sa));
|
|
s->sa.sin_family = AF_INET;
|
|
memcpy ((void *)&s->sa.sin_addr, (void *)s->hp->h_addr, s->hp->h_length);
|
|
s->portNo = portNo;
|
|
s->sa.sin_port = htons (portNo);
|
|
|
|
/* Open a TCP socket (an Internet stream socket). */
|
|
|
|
s->sockFd = socket (s->hp->h_addrtype, SOCK_STREAM, 0);
|
|
return s;
|
|
}
|
|
|
|
/* tcpClientSocketIP returns a file descriptor (socket) which has
|
|
connected to, ip:portNo. */
|
|
|
|
extern "C" tcpClientState *
|
|
EXPORT(tcpClientSocketIP) (unsigned int ip, int portNo)
|
|
{
|
|
tcpClientState *s = (tcpClientState *)malloc (sizeof (tcpClientState));
|
|
|
|
if (s == NULL)
|
|
ERROR ("no more memory");
|
|
|
|
/* Remove SIGPIPE which is raised on the server if the client is killed. */
|
|
signal (SIGPIPE, SIG_IGN);
|
|
|
|
memset ((void *)&s->sa, 0, sizeof (s->sa));
|
|
s->sa.sin_family = AF_INET;
|
|
memcpy ((void *)&s->sa.sin_addr, (void *)&ip, sizeof (ip));
|
|
s->portNo = portNo;
|
|
s->sa.sin_port = htons (portNo);
|
|
|
|
/* Open a TCP socket (an Internet stream socket). */
|
|
|
|
s->sockFd = socket (PF_INET, SOCK_STREAM, 0);
|
|
return s;
|
|
}
|
|
|
|
/* tcpClientConnect returns the file descriptor associated with s,
|
|
once a connect has been performed. */
|
|
|
|
extern "C" int
|
|
EXPORT(tcpClientConnect) (tcpClientState *s)
|
|
{
|
|
if (connect (s->sockFd, (struct sockaddr *)&s->sa, sizeof (s->sa)) < 0)
|
|
ERROR ("failed to connect to the TCP server");
|
|
|
|
return s->sockFd;
|
|
}
|
|
|
|
/* tcpClientPortNo returns the portNo from structure s. */
|
|
|
|
extern "C" int
|
|
EXPORT(tcpClientPortNo) (tcpClientState *s)
|
|
{
|
|
return s->portNo;
|
|
}
|
|
|
|
/* tcpClientSocketFd returns the sockFd from structure s. */
|
|
|
|
extern "C" int
|
|
EXPORT(tcpClientSocketFd) (tcpClientState *s)
|
|
{
|
|
return s->sockFd;
|
|
}
|
|
|
|
/* tcpClientIP returns the sockFd from structure s. */
|
|
|
|
extern "C" int
|
|
EXPORT(tcpClientIP) (tcpClientState *s)
|
|
{
|
|
#if defined(DEBUGGING)
|
|
printf ("client ip = %s\n", inet_ntoa (s->sa.sin_addr.s_addr));
|
|
#endif
|
|
return s->sa.sin_addr.s_addr;
|
|
}
|
|
#endif
|
|
|
|
/* GNU Modula-2 link fodder. */
|
|
|
|
extern "C" void
|
|
M2EXPORT(init) (int, char *[], char *[])
|
|
{
|
|
}
|
|
|
|
extern "C" void
|
|
M2EXPORT(finish) (int, char *[], char *[])
|
|
{
|
|
}
|
|
|
|
extern "C" void
|
|
M2EXPORT(dep) (void)
|
|
{
|
|
}
|
|
|
|
extern "C" void __attribute__((__constructor__))
|
|
M2EXPORT(ctor) (void)
|
|
{
|
|
m2pim_M2RTS_RegisterModule ("sckt", M2LIBNAME,
|
|
M2EXPORT(init), M2EXPORT(finish),
|
|
M2EXPORT(dep));
|
|
}
|