mirror of https://github.com/macssh/macssh.git
This commit was manufactured by cvs2svn to create branch 'v22a-branch'.
Sprout from master 2002-11-22 16:49:58 UTC chombier 'CWPro8.3 Update' Delete: CVSROOT/checkoutlist CVSROOT/commitinfo CVSROOT/config CVSROOT/cvswrappers CVSROOT/editinfo CVSROOT/loginfo CVSROOT/modules CVSROOT/notify CVSROOT/rcsinfo CVSROOT/taginfo CVSROOT/verifymsg GUSI/DCon/Headers/DCon.h GUSI/Examples/GUSIFileTest.c GUSI/Examples/GUSIINETTest.c GUSI/Examples/GUSIPPCTest.c GUSI/Examples/GUSISocketTest.c GUSI/Examples/GUSITest (MSL).mcp.xml GUSI/Examples/GUSITest.c GUSI/Examples/GUSITest.h GUSI/Examples/GUSITest.r GUSI/Examples/GUSITest.rsrc GUSI/Examples/GUSITest_P.h GUSI/Examples/GUSIThreadTest.c GUSI/Examples/MSLGUSITest.pch GUSI/Examples/Makefile GUSI/GUSIConfig.mk GUSI/GUSIConfig/GUSIConfig GUSI/GUSI_Install.MPW GUSI/MANIFEST GUSI/MacDistr GUSI/Makefile.mk GUSI/README GUSI/STLport_Install.MPW GUSI/doc/GUSI.pdf GUSI/doc/GUSI_CW_Guide.pdf GUSI/doc/pod/GUSI.cmd GUSI/doc/pod/GUSI.pod GUSI/doc/pod/GUSI_Common.pod GUSI/doc/pod/GUSI_Files.pod GUSI/doc/pod/GUSI_Install.pod GUSI/doc/pod/GUSI_Misc.pod GUSI/doc/pod/GUSI_Sockets.pod GUSI/doc/pod/GUSI_Threads.pod GUSI/include/GUSIBasics.h GUSI/include/GUSIBuffer.h GUSI/include/GUSIConfig.h GUSI/include/GUSIContext.h GUSI/include/GUSIContextQueue.h GUSI/include/GUSIDCon.h GUSI/include/GUSIDescriptor.h GUSI/include/GUSIDevice.h GUSI/include/GUSIDiag.h GUSI/include/GUSIFSWrappers.h GUSI/include/GUSIFactory.h GUSI/include/GUSIFileSpec.h GUSI/include/GUSIForeignThreads.h GUSI/include/GUSIInet.h GUSI/include/GUSIInternal.h GUSI/include/GUSIMPW.h GUSI/include/GUSIMSL.h GUSI/include/GUSIMTInet.h GUSI/include/GUSIMTNetDB.h GUSI/include/GUSIMTTcp.h GUSI/include/GUSIMTUdp.h GUSI/include/GUSIMacFile.h GUSI/include/GUSINetDB.h GUSI/include/GUSINull.h GUSI/include/GUSIOTInet.h GUSI/include/GUSIOTNetDB.h GUSI/include/GUSIOpenTransport.h GUSI/include/GUSIPOSIX.h GUSI/include/GUSIPPC.h GUSI/include/GUSIPThread.h GUSI/include/GUSIPipe.h GUSI/include/GUSISIOUX.h GUSI/include/GUSISIOW.h GUSI/include/GUSISignal.h GUSI/include/GUSISocket.h GUSI/include/GUSISocketMixins.h GUSI/include/GUSISpecific.h GUSI/include/GUSITimer.h GUSI/include/arpa/inet.h GUSI/include/compat.h GUSI/include/dirent.h GUSI/include/errno.h GUSI/include/fcntl.h GUSI/include/inttypes.h GUSI/include/machine/ansi.h GUSI/include/machine/endian.h GUSI/include/machine/signal.h GUSI/include/net/if.h GUSI/include/netdb.h GUSI/include/netinet/in.h GUSI/include/netinet/tcp.h GUSI/include/pthread.h GUSI/include/sched.h GUSI/include/signal.h GUSI/include/sys/cdefs.h GUSI/include/sys/errno.h GUSI/include/sys/filio.h GUSI/include/sys/ioccom.h GUSI/include/sys/ioctl.h GUSI/include/sys/ppc.h GUSI/include/sys/signal.h GUSI/include/sys/socket.h GUSI/include/sys/sockio.h GUSI/include/sys/stat.h GUSI/include/sys/time.h GUSI/include/sys/ttycom.h GUSI/include/sys/types.h GUSI/include/sys/uio.h GUSI/include/sys/un.h GUSI/include/sys/unistd.h GUSI/include/unistd.h GUSI/include/utime.h GUSI/project/GUSI2.CWPro6.mcp GUSI/project/GUSI2.CWPro7.mcp GUSI/project/GUSI2.mcp GUSI/scripts/EzDepend GUSI/scripts/update-source GUSI/scripts/weavem GUSI/src/GUSI.tex GUSI/src/GUSIBasics.nw GUSI/src/GUSIBuffer.nw GUSI/src/GUSIConfig.nw GUSI/src/GUSIContext.nw GUSI/src/GUSIContextQueue.nw GUSI/src/GUSIDCon.nw GUSI/src/GUSIDescriptor.nw GUSI/src/GUSIDevice.nw GUSI/src/GUSIDiag.nw GUSI/src/GUSIFSWrappers.nw GUSI/src/GUSIFactory.nw GUSI/src/GUSIFileSpec.nw GUSI/src/GUSIForeignThreads.nw GUSI/src/GUSIInet.nw GUSI/src/GUSIMPW.nw GUSI/src/GUSIMPWStdio.nw GUSI/src/GUSIMSL.nw GUSI/src/GUSIMTInet.nw GUSI/src/GUSIMTNetDB.nw GUSI/src/GUSIMTTcp.nw GUSI/src/GUSIMTUdp.nw GUSI/src/GUSIMacFile.nw GUSI/src/GUSINetDB.nw GUSI/src/GUSINull.nw GUSI/src/GUSIOTInet.nw GUSI/src/GUSIOTNetDB.nw GUSI/src/GUSIOpenTransport.nw GUSI/src/GUSIPOSIX.nw GUSI/src/GUSIPPC.nw GUSI/src/GUSIPThread.nw GUSI/src/GUSIPipe.nw GUSI/src/GUSISIOUX.nw GUSI/src/GUSISIOW.nw GUSI/src/GUSISfio.nw GUSI/src/GUSISignal.nw GUSI/src/GUSISocket.nw GUSI/src/GUSISocketMixins.nw GUSI/src/GUSISpecific.nw GUSI/src/GUSITimer.nw GUSI/src/Makefile.mk GUSI/src/Makefile.nw GUSI/src/tangled/GUSIBasics.cp GUSI/src/tangled/GUSIBuffer.cp GUSI/src/tangled/GUSIConfig.cp GUSI/src/tangled/GUSIContext.cp GUSI/src/tangled/GUSIContextQueue.cp GUSI/src/tangled/GUSIDCon.cp GUSI/src/tangled/GUSIDescriptor.cp GUSI/src/tangled/GUSIDevice.cp GUSI/src/tangled/GUSIDiag.cp GUSI/src/tangled/GUSIFSWrappers.cp GUSI/src/tangled/GUSIFactory.cp GUSI/src/tangled/GUSIFileSpec.cp GUSI/src/tangled/GUSIForeignThreads.cp GUSI/src/tangled/GUSIInet.cp GUSI/src/tangled/GUSIMPW.cp GUSI/src/tangled/GUSIMPWStdio.cp GUSI/src/tangled/GUSIMSL.cp GUSI/src/tangled/GUSIMTInet.cp GUSI/src/tangled/GUSIMTNetDB.cp GUSI/src/tangled/GUSIMTTcp.cp GUSI/src/tangled/GUSIMTUdp.cp GUSI/src/tangled/GUSIMacFile.cp GUSI/src/tangled/GUSINetDB.cp GUSI/src/tangled/GUSINull.cp GUSI/src/tangled/GUSIOTInet.cp GUSI/src/tangled/GUSIOTNetDB.cp GUSI/src/tangled/GUSIOpenTransport.cp GUSI/src/tangled/GUSIPOSIX.cp GUSI/src/tangled/GUSIPPC.cp GUSI/src/tangled/GUSIPThread.cp GUSI/src/tangled/GUSIPipe.cp GUSI/src/tangled/GUSISIOUX.cp GUSI/src/tangled/GUSISIOW.cp GUSI/src/tangled/GUSISfio.cp GUSI/src/tangled/GUSISignal.cp GUSI/src/tangled/GUSISocket.cp GUSI/src/tangled/GUSISocketMixins.cp GUSI/src/tangled/GUSISpecific.cp GUSI/src/tangled/GUSITimer.cp GUSI/test/GUSIConfig_MTINET.cp GUSI/test/GUSIConfig_OTINET.cp GUSI/test/Makefile.mk GUSI/test/Makefile.nw GUSI/test/TestDaytime.nw GUSI/test/TestDuplicate.nw GUSI/test/TestFileSpecs.nw GUSI/test/TestHTGet.nw GUSI/test/TestHttpD.nw GUSI/test/TestMPWFD.nw GUSI/test/TestMSLTee.nw GUSI/test/TestMTTcp.nw GUSI/test/TestMutex.nw GUSI/test/TestPipes.nw GUSI/test/TestTimers.nw GUSI/test/tangled/TestDaytime.cp GUSI/test/tangled/TestDuplicate.cp GUSI/test/tangled/TestFileSpecs.cp GUSI/test/tangled/TestHTGet.cp GUSI/test/tangled/TestHttpD.cp GUSI/test/tangled/TestMPWFD.cp GUSI/test/tangled/TestMSLTee.cp GUSI/test/tangled/TestMTTcp.cp GUSI/test/tangled/TestMutex.cp GUSI/test/tangled/TestPipes.cp GUSI/test/tangled/TestTimers.cp gmp/.gdbinit gmp/AUTHORS gmp/COPYING gmp/COPYING.LIB gmp/ChangeLog gmp/INSTALL gmp/MacOS/.cvsignore gmp/MacOS/config.h gmp/MacOS/gmp-mparam.h gmp/MacOS/gmp.CWPro6.mcp gmp/MacOS/gmp.CWPro7.mcp gmp/MacOS/gmp.mcp gmp/MacOS/gmpprefix.h gmp/MacOS/gmpprefix68k.h gmp/MacOS/gmpprefixcarb.h gmp/MacOS/gmpprefixppc.h gmp/MacOS/mparam/mparam.mcp gmp/MacOS/mparam/mparam.mcp.xml gmp/MacOS/mparam/prefix.h gmp/Makefile.am gmp/Makefile.in gmp/NEWS gmp/README gmp/acconfig.h gmp/acinclude.m4 gmp/aclocal.m4 gmp/ansi2knr.1 gmp/ansi2knr.c gmp/assert.c gmp/compat.c gmp/config.guess gmp/config.in gmp/config.sub gmp/configure gmp/configure.in gmp/demos/Makefile.am gmp/demos/Makefile.in gmp/demos/calc.c gmp/demos/calc.h gmp/demos/calc.y gmp/demos/calclex.c gmp/demos/calclex.l gmp/demos/factorize.c gmp/demos/isprime.c gmp/demos/pexpr.c gmp/demos/primes.c gmp/demos/qcn.c gmp/depcomp gmp/doc/assembly_code gmp/doc/configuration gmp/doc/isa_abi_headache gmp/doc/multiplication gmp/doc/projects.html gmp/doc/tasks.html gmp/errno.c gmp/extract-dbl.c gmp/gmp-impl.h gmp/gmp.h gmp/gmp.info gmp/gmp.info-1 gmp/gmp.info-2 gmp/gmp.info-3 gmp/gmp.info-4 gmp/gmp.texi gmp/insert-dbl.c gmp/install-sh gmp/longlong.h gmp/ltconfig gmp/ltmain.sh gmp/macos.1/Makefile.in gmp/macos.1/README gmp/macos.1/configure gmp/macos.1/unix2mac gmp/mdate-sh gmp/memory.c gmp/missing gmp/mkinstalldirs gmp/mp.h gmp/mp_bpl.c gmp/mp_clz_tab.c gmp/mp_minv_tab.c gmp/mp_set_fns.c gmp/mpbsd/Makefile.am gmp/mpbsd/Makefile.in gmp/mpbsd/itom.c gmp/mpbsd/mfree.c gmp/mpbsd/min.c gmp/mpbsd/mout.c gmp/mpbsd/move.c gmp/mpbsd/mtox.c gmp/mpbsd/sdiv.c gmp/mpbsd/tests/Makefile.am gmp/mpbsd/tests/Makefile.in gmp/mpbsd/tests/allfuns.c gmp/mpbsd/tests/dummy.c gmp/mpbsd/tests/t-misc.c gmp/mpbsd/xtom.c gmp/mpf/Makefile.am gmp/mpf/Makefile.in gmp/mpf/README gmp/mpf/abs.c gmp/mpf/add.c gmp/mpf/add_ui.c gmp/mpf/clear.c gmp/mpf/cmp.c gmp/mpf/cmp_si.c gmp/mpf/cmp_ui.c gmp/mpf/div.c gmp/mpf/div_2exp.c gmp/mpf/div_ui.c gmp/mpf/dump.c gmp/mpf/eq.c gmp/mpf/get_d.c gmp/mpf/get_prc.c gmp/mpf/get_str.c gmp/mpf/init.c gmp/mpf/init2.c gmp/mpf/inp_str.c gmp/mpf/integer.c gmp/mpf/integerceil.c gmp/mpf/integerfloor.c gmp/mpf/integertrunc.c gmp/mpf/iset.c gmp/mpf/iset_d.c gmp/mpf/iset_si.c gmp/mpf/iset_str.c gmp/mpf/iset_ui.c gmp/mpf/mul.c gmp/mpf/mul_2exp.c gmp/mpf/mul_ui.c gmp/mpf/neg.c gmp/mpf/out_str.c gmp/mpf/pow_ui.c gmp/mpf/random2.c gmp/mpf/reldiff.c gmp/mpf/set.c gmp/mpf/set_d.c gmp/mpf/set_dfl_prec.c gmp/mpf/set_prc.c gmp/mpf/set_prc_raw.c gmp/mpf/set_q.c gmp/mpf/set_si.c gmp/mpf/set_str.c gmp/mpf/set_ui.c gmp/mpf/set_z.c gmp/mpf/size.c gmp/mpf/sqrt.c gmp/mpf/sqrt_ui.c gmp/mpf/sub.c gmp/mpf/sub_ui.c gmp/mpf/swap.c gmp/mpf/tests/Makefile.am gmp/mpf/tests/Makefile.in gmp/mpf/tests/ref.c gmp/mpf/tests/reuse.c gmp/mpf/tests/t-add.c gmp/mpf/tests/t-conv.c gmp/mpf/tests/t-dm2exp.c gmp/mpf/tests/t-get_d.c gmp/mpf/tests/t-misc.c gmp/mpf/tests/t-muldiv.c gmp/mpf/tests/t-sqrt.c gmp/mpf/tests/t-sub.c gmp/mpf/ui_div.c gmp/mpf/ui_sub.c gmp/mpf/urandomb.c gmp/mpfr/Makefile.am gmp/mpfr/Makefile.in gmp/mpfr/README gmp/mpfr/add.c gmp/mpfr/add_ulp.c gmp/mpfr/agm.c gmp/mpfr/clear.c gmp/mpfr/cmp.c gmp/mpfr/cmp_ui.c gmp/mpfr/div.c gmp/mpfr/div_2exp.c gmp/mpfr/div_ui.c gmp/mpfr/exp.c gmp/mpfr/get_str.c gmp/mpfr/init.c gmp/mpfr/karadiv.c gmp/mpfr/karasqrt.c gmp/mpfr/log.c gmp/mpfr/log2.c gmp/mpfr/mpfr-impl.h gmp/mpfr/mpfr.h gmp/mpfr/mul.c gmp/mpfr/mul_2exp.c gmp/mpfr/mul_ui.c gmp/mpfr/neg.c gmp/mpfr/out_str.c gmp/mpfr/pi.c gmp/mpfr/pow.c gmp/mpfr/print_raw.c gmp/mpfr/print_rnd_mode.c gmp/mpfr/random.c gmp/mpfr/round.c gmp/mpfr/set.c gmp/mpfr/set_d.c gmp/mpfr/set_dfl_prec.c gmp/mpfr/set_dfl_rnd.c gmp/mpfr/set_f.c gmp/mpfr/set_prec.c gmp/mpfr/set_si.c gmp/mpfr/set_str_raw.c gmp/mpfr/set_z.c gmp/mpfr/sqrt.c gmp/mpfr/sub.c gmp/mpfr/tests/Makefile.am gmp/mpfr/tests/Makefile.in gmp/mpfr/tests/dummy.c gmp/mpfr/tests/tcan_round.c gmp/mpfr/tests/tcmp.c gmp/mpfr/tests/tcmp2.c gmp/mpfr/tests/tcmp_ui.c gmp/mpfr/tests/tlog2.c gmp/mpfr/tests/tmul_2exp.c gmp/mpfr/tests/tmul_ui.c gmp/mpfr/tests/tpi.c gmp/mpfr/tests/tround.c gmp/mpfr/tests/tset_d.c gmp/mpfr/tests/tset_si.c gmp/mpfr/tests/tset_str.c gmp/mpfr/tests/tset_z.c gmp/mpfr/tests/tzeta.c gmp/mpfr/zeta.c gmp/mpn/Makefile.am gmp/mpn/Makefile.in gmp/mpn/README gmp/mpn/a29k/add_n.s gmp/mpn/a29k/addmul_1.s gmp/mpn/a29k/lshift.s gmp/mpn/a29k/mul_1.s gmp/mpn/a29k/rshift.s gmp/mpn/a29k/sub_n.s gmp/mpn/a29k/submul_1.s gmp/mpn/a29k/udiv.s gmp/mpn/a29k/umul.s gmp/mpn/alpha/README gmp/mpn/alpha/add_n.asm gmp/mpn/alpha/addmul_1.asm gmp/mpn/alpha/cntlz.asm gmp/mpn/alpha/default.m4 gmp/mpn/alpha/ev5/add_n.asm gmp/mpn/alpha/ev5/lshift.asm gmp/mpn/alpha/ev5/rshift.asm gmp/mpn/alpha/ev5/sub_n.asm gmp/mpn/alpha/ev6/addmul_1.asm gmp/mpn/alpha/ev6/gmp-mparam.h gmp/mpn/alpha/gmp-mparam.h gmp/mpn/alpha/invert_limb.asm gmp/mpn/alpha/lshift.asm gmp/mpn/alpha/mul_1.asm gmp/mpn/alpha/rshift.asm gmp/mpn/alpha/sub_n.asm gmp/mpn/alpha/submul_1.asm gmp/mpn/alpha/udiv_qrnnd.S gmp/mpn/alpha/umul.asm gmp/mpn/alpha/unicos.m4 gmp/mpn/arm/add_n.S gmp/mpn/arm/addmul_1.S gmp/mpn/arm/gmp-mparam.h gmp/mpn/arm/mul_1.S gmp/mpn/arm/sub_n.S gmp/mpn/asm-defs.m4 gmp/mpn/clipper/add_n.s gmp/mpn/clipper/mul_1.s gmp/mpn/clipper/sub_n.s gmp/mpn/cray/README gmp/mpn/cray/add_n.c gmp/mpn/cray/addmul_1.c gmp/mpn/cray/gmp-mparam.h gmp/mpn/cray/mul_1.c gmp/mpn/cray/mulww.f gmp/mpn/cray/mulww.s gmp/mpn/cray/sub_n.c gmp/mpn/cray/submul_1.c gmp/mpn/generic/add_n.c gmp/mpn/generic/addmul_1.c gmp/mpn/generic/addsub_n.c gmp/mpn/generic/bdivmod.c gmp/mpn/generic/bz_divrem_n.c gmp/mpn/generic/cmp.c gmp/mpn/generic/diveby3.c gmp/mpn/generic/divrem.c gmp/mpn/generic/divrem_1.c gmp/mpn/generic/divrem_2.c gmp/mpn/generic/dump.c gmp/mpn/generic/gcd.c gmp/mpn/generic/gcd_1.c gmp/mpn/generic/gcdext.c gmp/mpn/generic/get_str.c gmp/mpn/generic/gmp-mparam.h gmp/mpn/generic/hamdist.c gmp/mpn/generic/inlines.c gmp/mpn/generic/jacbase.c gmp/mpn/generic/lshift.c gmp/mpn/generic/mod_1.c gmp/mpn/generic/mod_1_rs.c gmp/mpn/generic/mul.c gmp/mpn/generic/mul_1.c gmp/mpn/generic/mul_basecase.c gmp/mpn/generic/mul_fft.c gmp/mpn/generic/mul_n.c gmp/mpn/generic/perfsqr.c gmp/mpn/generic/popcount.c gmp/mpn/generic/pre_mod_1.c gmp/mpn/generic/random.c gmp/mpn/generic/random2.c gmp/mpn/generic/rshift.c gmp/mpn/generic/sb_divrem_mn.c gmp/mpn/generic/scan0.c gmp/mpn/generic/scan1.c gmp/mpn/generic/set_str.c gmp/mpn/generic/sqr_basecase.c gmp/mpn/generic/sqrtrem.c gmp/mpn/generic/sub_n.c gmp/mpn/generic/submul_1.c gmp/mpn/generic/tdiv_qr.c gmp/mpn/generic/udiv_w_sdiv.c gmp/mpn/hppa/README gmp/mpn/hppa/add_n.s gmp/mpn/hppa/gmp-mparam.h gmp/mpn/hppa/hppa1_1/addmul_1.s gmp/mpn/hppa/hppa1_1/mul_1.s gmp/mpn/hppa/hppa1_1/pa7100/add_n.s gmp/mpn/hppa/hppa1_1/pa7100/addmul_1.S gmp/mpn/hppa/hppa1_1/pa7100/lshift.s gmp/mpn/hppa/hppa1_1/pa7100/rshift.s gmp/mpn/hppa/hppa1_1/pa7100/sub_n.s gmp/mpn/hppa/hppa1_1/pa7100/submul_1.S gmp/mpn/hppa/hppa1_1/submul_1.s gmp/mpn/hppa/hppa1_1/udiv_qrnnd.S gmp/mpn/hppa/hppa1_1/umul.s gmp/mpn/hppa/hppa2_0/add_n.s gmp/mpn/hppa/hppa2_0/sub_n.s gmp/mpn/hppa/lshift.s gmp/mpn/hppa/rshift.s gmp/mpn/hppa/sub_n.s gmp/mpn/hppa/udiv_qrnnd.s gmp/mpn/i960/README gmp/mpn/i960/add_n.s gmp/mpn/i960/addmul_1.s gmp/mpn/i960/mul_1.s gmp/mpn/i960/sub_n.s gmp/mpn/lisp/gmpasm-mode.el gmp/mpn/m68k/add_n.S gmp/mpn/m68k/asm_syntax.h gmp/mpn/m68k/lshift.S gmp/mpn/m68k/mc68020/addmul_1.S gmp/mpn/m68k/mc68020/mul_1.S gmp/mpn/m68k/mc68020/submul_1.S gmp/mpn/m68k/mc68020/udiv.S gmp/mpn/m68k/mc68020/umul.S gmp/mpn/m68k/mpn68k.c gmp/mpn/m68k/rshift.S gmp/mpn/m68k/sub_n.S gmp/mpn/m68k/syntax.h gmp/mpn/m88k/add_n.s gmp/mpn/m88k/mc88110/add_n.S gmp/mpn/m88k/mc88110/addmul_1.s gmp/mpn/m88k/mc88110/mul_1.s gmp/mpn/m88k/mc88110/sub_n.S gmp/mpn/m88k/mul_1.s gmp/mpn/m88k/sub_n.s gmp/mpn/mips2/add_n.s gmp/mpn/mips2/addmul_1.s gmp/mpn/mips2/lshift.s gmp/mpn/mips2/mul_1.s gmp/mpn/mips2/rshift.s gmp/mpn/mips2/sub_n.s gmp/mpn/mips2/submul_1.s gmp/mpn/mips2/umul.s gmp/mpn/mips3/README gmp/mpn/mips3/add_n.s gmp/mpn/mips3/addmul_1.s gmp/mpn/mips3/gmp-mparam.h gmp/mpn/mips3/lshift.s gmp/mpn/mips3/mul_1.s gmp/mpn/mips3/rshift.s gmp/mpn/mips3/sub_n.s gmp/mpn/mips3/submul_1.s gmp/mpn/mp_bases.c gmp/mpn/ns32k/add_n.s gmp/mpn/ns32k/addmul_1.s gmp/mpn/ns32k/mul_1.s gmp/mpn/ns32k/sub_n.s gmp/mpn/ns32k/submul_1.s gmp/mpn/pa64/README gmp/mpn/pa64/add_n.s gmp/mpn/pa64/addmul_1.S gmp/mpn/pa64/gmp-mparam.h gmp/mpn/pa64/lshift.s gmp/mpn/pa64/mul_1.S gmp/mpn/pa64/rshift.s gmp/mpn/pa64/sub_n.s gmp/mpn/pa64/submul_1.S gmp/mpn/pa64/udiv_qrnnd.c gmp/mpn/pa64/umul_ppmm.S gmp/mpn/pa64w/README gmp/mpn/pa64w/add_n.s gmp/mpn/pa64w/addmul_1.S gmp/mpn/pa64w/gmp-mparam.h gmp/mpn/pa64w/lshift.s gmp/mpn/pa64w/mul_1.S gmp/mpn/pa64w/rshift.s gmp/mpn/pa64w/sub_n.s gmp/mpn/pa64w/submul_1.S gmp/mpn/pa64w/udiv_qrnnd.c gmp/mpn/pa64w/umul_ppmm.S gmp/mpn/power/add_n.s gmp/mpn/power/addmul_1.s gmp/mpn/power/lshift.s gmp/mpn/power/mul_1.s gmp/mpn/power/rshift.s gmp/mpn/power/sdiv.s gmp/mpn/power/sub_n.s gmp/mpn/power/submul_1.s gmp/mpn/power/umul.s gmp/mpn/powerpc32/add_n.asm gmp/mpn/powerpc32/addmul_1.asm gmp/mpn/powerpc32/aix.m4 gmp/mpn/powerpc32/gmp-mparam.h gmp/mpn/powerpc32/lshift.asm gmp/mpn/powerpc32/mpnppc32.c gmp/mpn/powerpc32/mul_1.asm gmp/mpn/powerpc32/regmap.m4 gmp/mpn/powerpc32/rshift.asm gmp/mpn/powerpc32/sub_n.asm gmp/mpn/powerpc32/submul_1.asm gmp/mpn/powerpc32/umul.asm gmp/mpn/powerpc64/README gmp/mpn/powerpc64/add_n.asm gmp/mpn/powerpc64/addmul_1.asm gmp/mpn/powerpc64/addsub_n.asm gmp/mpn/powerpc64/aix.m4 gmp/mpn/powerpc64/copyd.asm gmp/mpn/powerpc64/copyi.asm gmp/mpn/powerpc64/gmp-mparam.h gmp/mpn/powerpc64/lshift.asm gmp/mpn/powerpc64/mul_1.asm gmp/mpn/powerpc64/rshift.asm gmp/mpn/powerpc64/sub_n.asm gmp/mpn/powerpc64/submul_1.asm gmp/mpn/pyr/add_n.s gmp/mpn/pyr/addmul_1.s gmp/mpn/pyr/mul_1.s gmp/mpn/pyr/sub_n.s gmp/mpn/sh/add_n.s gmp/mpn/sh/sh2/addmul_1.s gmp/mpn/sh/sh2/mul_1.s gmp/mpn/sh/sh2/submul_1.s gmp/mpn/sh/sub_n.s gmp/mpn/sparc32/README gmp/mpn/sparc32/add_n.asm gmp/mpn/sparc32/addmul_1.asm gmp/mpn/sparc32/lshift.asm gmp/mpn/sparc32/mul_1.asm gmp/mpn/sparc32/rshift.asm gmp/mpn/sparc32/sub_n.asm gmp/mpn/sparc32/submul_1.asm gmp/mpn/sparc32/udiv_fp.asm gmp/mpn/sparc32/udiv_nfp.asm gmp/mpn/sparc32/umul.asm gmp/mpn/sparc32/v8/addmul_1.asm gmp/mpn/sparc32/v8/mul_1.asm gmp/mpn/sparc32/v8/submul_1.asm gmp/mpn/sparc32/v8/supersparc/udiv.asm gmp/mpn/sparc32/v8/umul.asm gmp/mpn/sparc32/v9/README gmp/mpn/sparc32/v9/addmul_1.asm gmp/mpn/sparc32/v9/gmp-mparam.h gmp/mpn/sparc32/v9/mul_1.asm gmp/mpn/sparc32/v9/submul_1.asm gmp/mpn/sparc64/README gmp/mpn/sparc64/add_n.asm gmp/mpn/sparc64/addmul1h.asm gmp/mpn/sparc64/addmul_1.asm gmp/mpn/sparc64/copyi.asm gmp/mpn/sparc64/gmp-mparam.h gmp/mpn/sparc64/lshift.asm gmp/mpn/sparc64/mul_1.asm gmp/mpn/sparc64/mul_1h.asm gmp/mpn/sparc64/rshift.asm gmp/mpn/sparc64/sub_n.asm gmp/mpn/sparc64/submul1h.asm gmp/mpn/sparc64/submul_1.asm gmp/mpn/tests/Makefile.am gmp/mpn/tests/Makefile.in gmp/mpn/tests/README gmp/mpn/tests/add_n.c gmp/mpn/tests/addmul_1.c gmp/mpn/tests/copy.c gmp/mpn/tests/divmod_1.c gmp/mpn/tests/divrem.c gmp/mpn/tests/lshift.c gmp/mpn/tests/mul_1.c gmp/mpn/tests/ref.c gmp/mpn/tests/ref.h gmp/mpn/tests/rshift.c gmp/mpn/tests/spinner.c gmp/mpn/tests/sub_n.c gmp/mpn/tests/submul_1.c gmp/mpn/tests/trace.c gmp/mpn/tests/try.c gmp/mpn/tests/try.h gmp/mpn/tests/tst-addsub.c gmp/mpn/tests/x86call.asm gmp/mpn/tests/x86check.c gmp/mpn/thumb/add_n.s gmp/mpn/thumb/sub_n.s gmp/mpn/underscore.h gmp/mpn/vax/add_n.s gmp/mpn/vax/addmul_1.s gmp/mpn/vax/lshift.s gmp/mpn/vax/mul_1.s gmp/mpn/vax/rshift.s gmp/mpn/vax/sub_n.s gmp/mpn/vax/submul_1.s gmp/mpn/x86/README gmp/mpn/x86/README.family gmp/mpn/x86/addsub_n.S gmp/mpn/x86/aors_n.asm gmp/mpn/x86/aorsmul_1.asm gmp/mpn/x86/copyd.asm gmp/mpn/x86/copyi.asm gmp/mpn/x86/diveby3.asm gmp/mpn/x86/divrem_1.asm gmp/mpn/x86/k6/README gmp/mpn/x86/k6/aors_n.asm gmp/mpn/x86/k6/aorsmul_1.asm gmp/mpn/x86/k6/cross.pl gmp/mpn/x86/k6/diveby3.asm gmp/mpn/x86/k6/gmp-mparam.h gmp/mpn/x86/k6/k62mmx/copyd.asm gmp/mpn/x86/k6/k62mmx/copyi.asm gmp/mpn/x86/k6/k62mmx/lshift.asm gmp/mpn/x86/k6/k62mmx/rshift.asm gmp/mpn/x86/k6/mmx/com_n.asm gmp/mpn/x86/k6/mmx/logops_n.asm gmp/mpn/x86/k6/mmx/lshift.asm gmp/mpn/x86/k6/mmx/popham.asm gmp/mpn/x86/k6/mmx/rshift.asm gmp/mpn/x86/k6/mul_1.asm gmp/mpn/x86/k6/mul_basecase.asm gmp/mpn/x86/k6/sqr_basecase.asm gmp/mpn/x86/k7/README gmp/mpn/x86/k7/aors_n.asm gmp/mpn/x86/k7/aorsmul_1.asm gmp/mpn/x86/k7/diveby3.asm gmp/mpn/x86/k7/gmp-mparam.h gmp/mpn/x86/k7/mmx/copyd.asm gmp/mpn/x86/k7/mmx/copyi.asm gmp/mpn/x86/k7/mmx/divrem_1.asm gmp/mpn/x86/k7/mmx/lshift.asm gmp/mpn/x86/k7/mmx/mod_1.asm gmp/mpn/x86/k7/mmx/popham.asm gmp/mpn/x86/k7/mmx/rshift.asm gmp/mpn/x86/k7/mul_1.asm gmp/mpn/x86/k7/mul_basecase.asm gmp/mpn/x86/k7/sqr_basecase.asm gmp/mpn/x86/lshift.asm gmp/mpn/x86/mod_1.asm gmp/mpn/x86/mul_1.asm gmp/mpn/x86/mul_basecase.asm gmp/mpn/x86/p6/README gmp/mpn/x86/p6/aorsmul_1.asm gmp/mpn/x86/p6/diveby3.asm gmp/mpn/x86/p6/gmp-mparam.h gmp/mpn/x86/p6/mmx/divrem_1.asm gmp/mpn/x86/p6/mmx/mod_1.asm gmp/mpn/x86/p6/mmx/popham.asm gmp/mpn/x86/p6/p3mmx/popham.asm gmp/mpn/x86/p6/sqr_basecase.asm gmp/mpn/x86/pentium/README gmp/mpn/x86/pentium/aors_n.asm gmp/mpn/x86/pentium/aorsmul_1.asm gmp/mpn/x86/pentium/diveby3.asm gmp/mpn/x86/pentium/gmp-mparam.h gmp/mpn/x86/pentium/lshift.asm gmp/mpn/x86/pentium/mmx/gmp-mparam.h gmp/mpn/x86/pentium/mmx/lshift.asm gmp/mpn/x86/pentium/mmx/popham.asm gmp/mpn/x86/pentium/mmx/rshift.asm gmp/mpn/x86/pentium/mul_1.asm gmp/mpn/x86/pentium/mul_basecase.asm gmp/mpn/x86/pentium/rshift.asm gmp/mpn/x86/pentium/sqr_basecase.asm gmp/mpn/x86/rshift.asm gmp/mpn/x86/udiv.asm gmp/mpn/x86/umul.asm gmp/mpn/x86/x86-defs.m4 gmp/mpn/z8000/add_n.s gmp/mpn/z8000/gmp-mparam.h gmp/mpn/z8000/mul_1.s gmp/mpn/z8000/sub_n.s gmp/mpn/z8000x/add_n.s gmp/mpn/z8000x/sub_n.s gmp/mpq/Makefile.am gmp/mpq/Makefile.in gmp/mpq/add.c gmp/mpq/canonicalize.c gmp/mpq/clear.c gmp/mpq/cmp.c gmp/mpq/cmp_ui.c gmp/mpq/div.c gmp/mpq/equal.c gmp/mpq/get_d.c gmp/mpq/get_den.c gmp/mpq/get_num.c gmp/mpq/init.c gmp/mpq/inv.c gmp/mpq/mul.c gmp/mpq/neg.c gmp/mpq/out_str.c gmp/mpq/set.c gmp/mpq/set_d.c gmp/mpq/set_den.c gmp/mpq/set_num.c gmp/mpq/set_si.c gmp/mpq/set_ui.c gmp/mpq/set_z.c gmp/mpq/sub.c gmp/mpq/swap.c gmp/mpq/tests/Makefile.am gmp/mpq/tests/Makefile.in gmp/mpq/tests/t-cmp.c gmp/mpq/tests/t-cmp_ui.c gmp/mpq/tests/t-get_d.c gmp/mpz/Makefile.am gmp/mpz/Makefile.in gmp/mpz/README gmp/mpz/abs.c gmp/mpz/add.c gmp/mpz/add_ui.c gmp/mpz/addmul_ui.c gmp/mpz/and.c gmp/mpz/array_init.c gmp/mpz/bin_ui.c gmp/mpz/bin_uiui.c gmp/mpz/cdiv_q.c gmp/mpz/cdiv_q_ui.c gmp/mpz/cdiv_qr.c gmp/mpz/cdiv_qr_ui.c gmp/mpz/cdiv_r.c gmp/mpz/cdiv_r_ui.c gmp/mpz/cdiv_ui.c gmp/mpz/clear.c gmp/mpz/clrbit.c gmp/mpz/cmp.c gmp/mpz/cmp_si.c gmp/mpz/cmp_ui.c gmp/mpz/cmpabs.c gmp/mpz/cmpabs_ui.c gmp/mpz/com.c gmp/mpz/divexact.c gmp/mpz/dump.c gmp/mpz/fac_ui.c gmp/mpz/fdiv_q.c gmp/mpz/fdiv_q_2exp.c gmp/mpz/fdiv_q_ui.c gmp/mpz/fdiv_qr.c gmp/mpz/fdiv_qr_ui.c gmp/mpz/fdiv_r.c gmp/mpz/fdiv_r_2exp.c gmp/mpz/fdiv_r_ui.c gmp/mpz/fdiv_ui.c gmp/mpz/fib_ui.c gmp/mpz/fits_sint_p.c gmp/mpz/fits_slong_p.c gmp/mpz/fits_sshort_p.c gmp/mpz/fits_uint_p.c gmp/mpz/fits_ulong_p.c gmp/mpz/fits_ushort_p.c gmp/mpz/gcd.c gmp/mpz/gcd_ui.c gmp/mpz/gcdext.c gmp/mpz/get_d.c gmp/mpz/get_si.c gmp/mpz/get_str.c gmp/mpz/get_ui.c gmp/mpz/getlimbn.c gmp/mpz/hamdist.c gmp/mpz/init.c gmp/mpz/inp_raw.c gmp/mpz/inp_str.c gmp/mpz/invert.c gmp/mpz/ior.c gmp/mpz/iset.c gmp/mpz/iset_d.c gmp/mpz/iset_si.c gmp/mpz/iset_str.c gmp/mpz/iset_ui.c gmp/mpz/jacobi.c gmp/mpz/kronsz.c gmp/mpz/kronuz.c gmp/mpz/kronzs.c gmp/mpz/kronzu.c gmp/mpz/lcm.c gmp/mpz/legendre.c gmp/mpz/mod.c gmp/mpz/mul.c gmp/mpz/mul_2exp.c gmp/mpz/mul_si.c gmp/mpz/mul_siui.c gmp/mpz/mul_ui.c gmp/mpz/neg.c gmp/mpz/nextprime.c gmp/mpz/out_raw.c gmp/mpz/out_str.c gmp/mpz/perfpow.c gmp/mpz/perfsqr.c gmp/mpz/popcount.c gmp/mpz/pow_ui.c gmp/mpz/powm.c gmp/mpz/powm_ui.c gmp/mpz/pprime_p.c gmp/mpz/random.c gmp/mpz/random2.c gmp/mpz/realloc.c gmp/mpz/remove.c gmp/mpz/root.c gmp/mpz/rrandomb.c gmp/mpz/scan0.c gmp/mpz/scan1.c gmp/mpz/set.c gmp/mpz/set_d.c gmp/mpz/set_f.c gmp/mpz/set_q.c gmp/mpz/set_si.c gmp/mpz/set_str.c gmp/mpz/set_ui.c gmp/mpz/setbit.c gmp/mpz/size.c gmp/mpz/sizeinbase.c gmp/mpz/sqrt.c gmp/mpz/sqrtrem.c gmp/mpz/sub.c gmp/mpz/sub_ui.c gmp/mpz/swap.c gmp/mpz/tdiv_q.c gmp/mpz/tdiv_q_2exp.c gmp/mpz/tdiv_q_ui.c gmp/mpz/tdiv_qr.c gmp/mpz/tdiv_qr_ui.c gmp/mpz/tdiv_r.c gmp/mpz/tdiv_r_2exp.c gmp/mpz/tdiv_r_ui.c gmp/mpz/tdiv_ui.c gmp/mpz/tests/Makefile.am gmp/mpz/tests/Makefile.in gmp/mpz/tests/bit.c gmp/mpz/tests/convert.c gmp/mpz/tests/dive.c gmp/mpz/tests/io.c gmp/mpz/tests/logic.c gmp/mpz/tests/reuse.c gmp/mpz/tests/t-2exp.c gmp/mpz/tests/t-bin.c gmp/mpz/tests/t-fdiv.c gmp/mpz/tests/t-fdiv_ui.c gmp/mpz/tests/t-gcd.c gmp/mpz/tests/t-jac.c gmp/mpz/tests/t-misc.c gmp/mpz/tests/t-mul.c gmp/mpz/tests/t-pow_ui.c gmp/mpz/tests/t-powm.c gmp/mpz/tests/t-powm_ui.c gmp/mpz/tests/t-root.c gmp/mpz/tests/t-sqrtrem.c gmp/mpz/tests/t-tdiv.c gmp/mpz/tests/t-tdiv_ui.c gmp/mpz/tstbit.c gmp/mpz/ui_pow_ui.c gmp/mpz/urandomb.c gmp/mpz/urandomm.c gmp/mpz/xor.c gmp/rand.c gmp/randclr.c gmp/randlc.c gmp/randlc2x.c gmp/randraw.c gmp/randsd.c gmp/randsdui.c gmp/stack-alloc.c gmp/stack-alloc.h gmp/stamp-h.in gmp/stamp-vti gmp/tests/Makefile.am gmp/tests/Makefile.in gmp/tests/rand/ChangeLog gmp/tests/rand/Makefile.am gmp/tests/rand/Makefile.in gmp/tests/rand/findlc.c gmp/tests/rand/gen.c gmp/tests/rand/gmpstat.h gmp/tests/rand/spect.c gmp/tests/rand/stat.c gmp/tests/rand/statlib.c gmp/tests/rand/t-rand.c gmp/tests/rand/zdiv_round.c gmp/texinfo.tex gmp/tune/Makefile.am gmp/tune/Makefile.in gmp/tune/README gmp/tune/alpha.asm gmp/tune/common.c gmp/tune/hppa.asm gmp/tune/hppa2.asm gmp/tune/noop.c gmp/tune/pentium.asm gmp/tune/sparcv9.asm gmp/tune/speed-ext.c gmp/tune/speed.c gmp/tune/speed.h gmp/tune/time.c gmp/tune/tuneup.c gmp/urandom.h gmp/version.c gmp/version.texi lsh/ANNOUNCE lsh/AUTHORS lsh/COPYING lsh/ChangeLog lsh/ChangeLog.1 lsh/FAQ lsh/MacOS/.cvsignore lsh/MacOS/desdata/desdata.mcp.xml lsh/MacOS/desdata/prefix.h lsh/MacOS/digit_table/digit_table.mcp.xml lsh/MacOS/digit_table/prefix.h lsh/MacOS/generate_q/generate_q.mcp.xml lsh/MacOS/generate_q/prefix.h lsh/MacOS/include/grp.h lsh/MacOS/include/netinet/in_systm.h lsh/MacOS/include/netinet/ip.h lsh/MacOS/include/pwd.h lsh/MacOS/include/sys/param.h lsh/MacOS/include/sys/syslog.h lsh/MacOS/include/sysexits.h lsh/MacOS/include/syslog.h lsh/MacOS/include/termios.h lsh/MacOS/lsh.CWPro6.mcp lsh/MacOS/lsh.CWPro7.mcp lsh/MacOS/lsh.mcp lsh/MacOS/lshdll.CWPro6.mcp lsh/MacOS/lshdll.mcp lsh/MacOS/lshdll.mcp.exp lsh/MacOS/lshmaccvs.CWPro6.mcp lsh/MacOS/lshmaccvs.mcp lsh/MacOS/lshmaccvs.mcp.exp lsh/MacOS/prime_table/prefix.h lsh/MacOS/prime_table/prime_table.mcp.xml lsh/MacOS/src/GUSIConfig.cpp lsh/MacOS/src/GUSIPatches.cp lsh/MacOS/src/GUSISIOUX.cp lsh/MacOS/src/GUSITTY.cp lsh/MacOS/src/GUSITTY.h lsh/MacOS/src/MemPool.c lsh/MacOS/src/MemPool.h lsh/MacOS/src/PasswordDialog.c lsh/MacOS/src/PasswordDialog.h lsh/MacOS/src/PasswordDialog.rsrc lsh/MacOS/src/SIOUX.c lsh/MacOS/src/SIOUXMenus.c lsh/MacOS/src/console.stubs.c lsh/MacOS/src/dlltest.c lsh/MacOS/src/lsh_context.h lsh/MacOS/src/lsh_dll.c lsh/MacOS/src/lsh_dll.cp lsh/MacOS/src/lsh_dll.h lsh/MacOS/src/lsh_evt.c lsh/MacOS/src/lsh_maccvs.cpp lsh/MacOS/src/lshprefix.carb.h lsh/MacOS/src/lshprefix.h lsh/MacOS/src/macos_random.c lsh/MacOS/src/macosmain.c lsh/MacOS/src/strcase.c lsh/MacOS/src/werror.c lsh/Makefile.am lsh/Makefile.am.in lsh/Makefile.in lsh/NEWS lsh/README lsh/acconfig.h lsh/acinclude.m4 lsh/aclocal.m4 lsh/config.h.in lsh/configure lsh/configure.in lsh/contrib/Makefile.am lsh/contrib/Makefile.in lsh/contrib/README lsh/contrib/lsh.spec lsh/contrib/lsh.spec.in lsh/contrib/lshd.debian.init lsh/contrib/lshd.rhlinux.init lsh/distribution-key.gpg lsh/doc/DSA.5 lsh/doc/HACKING lsh/doc/Makefile.am lsh/doc/Makefile.am.in lsh/doc/Makefile.in lsh/doc/NOTES lsh/doc/PORTS lsh/doc/SHA.5 lsh/doc/SPKI.5 lsh/doc/TASKLIST lsh/doc/TODO lsh/doc/configuration.txt lsh/doc/fixff.pl lsh/doc/fixff.sh lsh/doc/gateway-mode.txt lsh/doc/lsh.1 lsh/doc/lsh.html lsh/doc/lsh.info lsh/doc/lsh.texinfo lsh/doc/lsh_keygen.1 lsh/doc/lsh_writekey.1 lsh/doc/lshd.8 lsh/doc/secsh.5 lsh/doc/srp-spec.nroff lsh/doc/srp-spec.txt lsh/doc/texinfo.tex lsh/install-sh lsh/make_am lsh/misc/Makefile.am lsh/misc/Makefile.in lsh/misc/bootstrap.sh lsh/misc/ctags.mk lsh/misc/libgcc2.c-patch lsh/misc/make-dist lsh/missing lsh/mkinstalldirs lsh/src/.dist_classes lsh/src/.dist_headers lsh/src/Makefile.am lsh/src/Makefile.am.in lsh/src/Makefile.in lsh/src/abstract_compress.c lsh/src/abstract_compress.h lsh/src/abstract_compress.h.x lsh/src/abstract_crypto.c lsh/src/abstract_crypto.c.x lsh/src/abstract_crypto.h lsh/src/abstract_crypto.h.x lsh/src/abstract_io.c lsh/src/abstract_io.h lsh/src/abstract_io.h.x lsh/src/algorithms.c lsh/src/algorithms.h lsh/src/algorithms.h.x lsh/src/alist.c lsh/src/alist.c.x lsh/src/alist.h lsh/src/alist.h.x lsh/src/arcfour.c lsh/src/arcfour.c.x lsh/src/argp/Makefile.am lsh/src/argp/Makefile.in lsh/src/argp/Versions lsh/src/argp/acconfig.h lsh/src/argp/acinclude.m4 lsh/src/argp/aclocal.m4 lsh/src/argp/argp-ba.c lsh/src/argp/argp-eexst.c lsh/src/argp/argp-fmtstream.c lsh/src/argp/argp-fmtstream.h lsh/src/argp/argp-help.c lsh/src/argp/argp-namefrob.h lsh/src/argp/argp-parse.c lsh/src/argp/argp-pv.c lsh/src/argp/argp-pvh.c lsh/src/argp/argp-test.c lsh/src/argp/argp.h lsh/src/argp/config.h.in lsh/src/argp/configure lsh/src/argp/configure.in lsh/src/argp/mempcpy.c lsh/src/argp/stamp-h.in lsh/src/argp/strchrnul.c lsh/src/argp/strndup.c lsh/src/atoms.c lsh/src/atoms.h lsh/src/atoms.in lsh/src/atoms_defines.h lsh/src/atoms_gperf.c lsh/src/atoms_table.c lsh/src/bignum.c lsh/src/bignum.h lsh/src/blowfish.c lsh/src/blowfish.c.x lsh/src/cascade.c lsh/src/cascade.c.x lsh/src/cast.c lsh/src/cast.c.x lsh/src/cbc.c lsh/src/cbc.c.x lsh/src/channel.c lsh/src/channel.c.x lsh/src/channel.h lsh/src/channel.h.x lsh/src/channel_commands.c lsh/src/channel_commands.c.x lsh/src/channel_commands.h lsh/src/channel_commands.h.x lsh/src/channel_forward.c lsh/src/channel_forward.h lsh/src/channel_forward.h.x lsh/src/charset.c lsh/src/charset.h lsh/src/client.c lsh/src/client.c.x lsh/src/client.h lsh/src/client.h.x lsh/src/client_escape.c lsh/src/client_escape.c.x lsh/src/client_keyexchange.c lsh/src/client_keyexchange.c.x lsh/src/client_keyexchange.h lsh/src/client_pty.c lsh/src/client_pty.c.x lsh/src/client_session.c lsh/src/client_session.c.x lsh/src/client_userauth.c lsh/src/client_userauth.c.x lsh/src/client_userauth.h lsh/src/client_x11.c lsh/src/client_x11.c.x lsh/src/combinators.c lsh/src/combinators.c.x lsh/src/command.c lsh/src/command.c.x lsh/src/command.h lsh/src/command.h.x lsh/src/compress.c lsh/src/compress.c.x lsh/src/compress.h lsh/src/connection.c lsh/src/connection.c.x lsh/src/connection.h lsh/src/connection.h.x lsh/src/connection_commands.c lsh/src/connection_commands.h lsh/src/connection_commands.h.x lsh/src/crypto.h lsh/src/daemon.c lsh/src/daemon.h lsh/src/debug.c lsh/src/debug.c.x lsh/src/debug.h lsh/src/des.c lsh/src/des.c.x lsh/src/dh_exchange.c lsh/src/digit_table.c lsh/src/digit_table.h lsh/src/digits.c lsh/src/digits.h lsh/src/disconnect.c lsh/src/disconnect.h lsh/src/dsa.c lsh/src/dsa.c.x lsh/src/dsa.h lsh/src/dsa_keygen.c lsh/src/encrypt.c lsh/src/encrypt.c.x lsh/src/encrypt.h lsh/src/exception.c lsh/src/exception.c.x lsh/src/exception.h lsh/src/exception.h.x lsh/src/format.c lsh/src/format.h lsh/src/gateway.c lsh/src/gateway.h lsh/src/gateway_channel.c lsh/src/gateway_channel.c.x lsh/src/gateway_channel.h lsh/src/gateway_channel.h.x lsh/src/gateway_commands.c lsh/src/gateway_commands.c.x lsh/src/gateway_commands.h lsh/src/gc.c lsh/src/gc.h lsh/src/handshake.c lsh/src/handshake.c.x lsh/src/handshake.h lsh/src/handshake.h.x lsh/src/hmac.c lsh/src/hmac.c.x lsh/src/idea.c lsh/src/interact.c lsh/src/interact.h lsh/src/interact.h.x lsh/src/invert-defs lsh/src/io.c lsh/src/io.c.x lsh/src/io.h lsh/src/io.h.x lsh/src/io_commands.c lsh/src/io_commands.c.x lsh/src/io_commands.h lsh/src/io_commands.h.x lsh/src/jpoll.c lsh/src/jpoll.h lsh/src/keyexchange.c lsh/src/keyexchange.c.x lsh/src/keyexchange.h lsh/src/keyexchange.h.x lsh/src/lcp lsh/src/list.c lsh/src/list.h lsh/src/list.h.x lsh/src/lookup_verifier.c lsh/src/lookup_verifier.h lsh/src/lookup_verifier.h.x lsh/src/lsh-authorize lsh/src/lsh-decode-key.c lsh/src/lsh-decode-key.c.x lsh/src/lsh-export-key.c lsh/src/lsh-export-key.c.x lsh/src/lsh-keygen.c lsh/src/lsh-keygen.c.x lsh/src/lsh-krb-checkpw.c lsh/src/lsh-writekey.c lsh/src/lsh-writekey.c.x lsh/src/lsh.c lsh/src/lsh.c.x lsh/src/lsh.h lsh/src/lsh_argp.h lsh/src/lsh_proxy.c lsh/src/lsh_proxy.c.x lsh/src/lsh_types.h lsh/src/lshd.c lsh/src/lshd.c.x lsh/src/lshg.c lsh/src/lshg.c.x lsh/src/md5.c lsh/src/md5.c.x lsh/src/memcmp.c lsh/src/memxor.c lsh/src/memxor.h lsh/src/nettle/AUTHORS lsh/src/nettle/COPYING lsh/src/nettle/ChangeLog lsh/src/nettle/INSTALL lsh/src/nettle/Makefile.am lsh/src/nettle/Makefile.in lsh/src/nettle/NEWS lsh/src/nettle/README lsh/src/nettle/aclocal.m4 lsh/src/nettle/aes.c lsh/src/nettle/aes.h lsh/src/nettle/arcfour.c lsh/src/nettle/arcfour.h lsh/src/nettle/blowfish.c lsh/src/nettle/blowfish.h lsh/src/nettle/cast128.c lsh/src/nettle/cast128.h lsh/src/nettle/cast128_sboxes.h lsh/src/nettle/config.h.in lsh/src/nettle/configure lsh/src/nettle/configure.in lsh/src/nettle/des.c lsh/src/nettle/des.h lsh/src/nettle/desCode.h lsh/src/nettle/descore.README lsh/src/nettle/desdata.c lsh/src/nettle/desinfo.h lsh/src/nettle/install-sh lsh/src/nettle/keymap.h lsh/src/nettle/macros.h lsh/src/nettle/md5.c lsh/src/nettle/md5.h lsh/src/nettle/memxor.c lsh/src/nettle/memxor.h lsh/src/nettle/missing lsh/src/nettle/mkinstalldirs lsh/src/nettle/nettle.html lsh/src/nettle/nettle.info lsh/src/nettle/nettle.texinfo lsh/src/nettle/parity.h lsh/src/nettle/rotors.h lsh/src/nettle/serpent.c lsh/src/nettle/serpent.h lsh/src/nettle/serpent_sboxes.h lsh/src/nettle/sha1.c lsh/src/nettle/sha1.h lsh/src/nettle/stamp-h.in lsh/src/nettle/testsuite/Makefile.am lsh/src/nettle/testsuite/Makefile.in lsh/src/nettle/testsuite/aes-test.c lsh/src/nettle/testsuite/aes-test.m4 lsh/src/nettle/testsuite/arcfour-test.c lsh/src/nettle/testsuite/arcfour-test.m4 lsh/src/nettle/testsuite/blowfish-test.c lsh/src/nettle/testsuite/blowfish-test.m4 lsh/src/nettle/testsuite/cast128-test.c lsh/src/nettle/testsuite/cast128-test.m4 lsh/src/nettle/testsuite/des-test.c lsh/src/nettle/testsuite/des-test.m4 lsh/src/nettle/testsuite/md5-test.c lsh/src/nettle/testsuite/md5-test.m4 lsh/src/nettle/testsuite/run-tests lsh/src/nettle/testsuite/serpent-test.c lsh/src/nettle/testsuite/serpent-test.m4 lsh/src/nettle/testsuite/sha1-test.c lsh/src/nettle/testsuite/sha1-test.m4 lsh/src/nettle/testsuite/testutils.c lsh/src/nettle/testsuite/testutils.h lsh/src/nettle/testsuite/twofish-test.c lsh/src/nettle/testsuite/twofish-test.m4 lsh/src/nettle/texinfo.tex lsh/src/nettle/twofish.c lsh/src/nettle/twofish.h lsh/src/packet_types.h lsh/src/pad.c lsh/src/pad.c.x lsh/src/pad.h lsh/src/parse.c lsh/src/parse.h lsh/src/parse_macros.h lsh/src/pkcs5-test.c lsh/src/pkcs5.c lsh/src/prime_table.c lsh/src/prime_table.h lsh/src/process_atoms lsh/src/proxy.c lsh/src/proxy.c.x lsh/src/proxy.h lsh/src/proxy_agentforward.c lsh/src/proxy_agentforward.h lsh/src/proxy_session.c lsh/src/proxy_session.c.x lsh/src/proxy_session.h lsh/src/proxy_tcpforward.c lsh/src/proxy_tcpforward.h lsh/src/proxy_userauth.c lsh/src/proxy_userauth.c.x lsh/src/proxy_userauth.h lsh/src/proxy_userauth.h.x lsh/src/proxy_x11forward.c lsh/src/proxy_x11forward.h lsh/src/publickey_crypto.c lsh/src/publickey_crypto.c.x lsh/src/publickey_crypto.h lsh/src/publickey_crypto.h.x lsh/src/queue.c lsh/src/queue.h lsh/src/queue.h.x lsh/src/randomness.c lsh/src/randomness.c.x lsh/src/randomness.h lsh/src/randomness.h.x lsh/src/read_base64.c lsh/src/read_base64.c.x lsh/src/read_data.c lsh/src/read_data.c.x lsh/src/read_data.h lsh/src/read_file.c lsh/src/read_file.c.x lsh/src/read_file.h lsh/src/read_line.c lsh/src/read_line.c.x lsh/src/read_line.h lsh/src/read_line.h.x lsh/src/read_packet.c lsh/src/read_packet.c.x lsh/src/read_packet.h lsh/src/reaper.c lsh/src/reaper.c.x lsh/src/reaper.h lsh/src/reaper.h.x lsh/src/resource.c lsh/src/resource.c.x lsh/src/resource.h lsh/src/resource.h.x lsh/src/rijndael.c lsh/src/rijndael.c.x lsh/src/rsa.c lsh/src/rsa.c.x lsh/src/rsa.h lsh/src/rsa.h.x lsh/src/rsa_keygen.c lsh/src/rsync/Makefile.am lsh/src/rsync/Makefile.in lsh/src/rsync/README lsh/src/rsync/checksum.c lsh/src/rsync/generate.c lsh/src/rsync/receive.c lsh/src/rsync/rsync.h lsh/src/rsync/send.c lsh/src/scm/Makefile.am lsh/src/scm/Makefile.am.in lsh/src/scm/Makefile.in lsh/src/scm/compiler.scm lsh/src/scm/gaba.scm lsh/src/scm/guile-compat.scm lsh/src/scm/make-char-classes.scm lsh/src/scm/scsh-compat.scm lsh/src/serpent.c lsh/src/serpent.c.x lsh/src/server.c lsh/src/server.c.x lsh/src/server.h lsh/src/server_authorization.c lsh/src/server_authorization.c.x lsh/src/server_authorization.h lsh/src/server_keyexchange.c lsh/src/server_keyexchange.c.x lsh/src/server_keyexchange.h lsh/src/server_password.c lsh/src/server_password.c.x lsh/src/server_pty.c lsh/src/server_pty.h lsh/src/server_pty.h.x lsh/src/server_publickey.c lsh/src/server_publickey.c.x lsh/src/server_session.c lsh/src/server_session.c.x lsh/src/server_session.h lsh/src/server_userauth.c lsh/src/server_userauth.c.x lsh/src/server_userauth.h lsh/src/server_userauth.h.x lsh/src/sexp-conv.c lsh/src/sexp-conv.c.x lsh/src/sexp.c lsh/src/sexp.c.x lsh/src/sexp.h lsh/src/sexp.h.x lsh/src/sexp_chars.in lsh/src/sexp_commands.c lsh/src/sexp_commands.c.x lsh/src/sexp_commands.h lsh/src/sexp_commands.h.x lsh/src/sexp_parser.c lsh/src/sexp_table.h lsh/src/sftp/Makefile.am lsh/src/sftp/Makefile.in lsh/src/sftp/acconfig.h lsh/src/sftp/aclocal.m4 lsh/src/sftp/buffer.c lsh/src/sftp/buffer.h lsh/src/sftp/client.c lsh/src/sftp/client.h lsh/src/sftp/config.h.in lsh/src/sftp/configure lsh/src/sftp/configure.in lsh/src/sftp/dump-hex.c lsh/src/sftp/filemode.c lsh/src/sftp/filemode.h lsh/src/sftp/idcache.c lsh/src/sftp/idcache.h lsh/src/sftp/sftp-server.c lsh/src/sftp/sftp-test-client.c lsh/src/sftp/sftp.h lsh/src/sftp/stamp-h.in lsh/src/sftp/testsuite/Makefile.am lsh/src/sftp/testsuite/Makefile.in lsh/src/sftp/testsuite/common.sh lsh/src/sftp/testsuite/connect-test lsh/src/sftp/testsuite/get-1-test lsh/src/sftp/testsuite/ls-1-test lsh/src/sftp/testsuite/ls-2-test lsh/src/sftp/testsuite/put-1-test lsh/src/sftp/testsuite/run-tests lsh/src/sftp/testsuite/setup-env lsh/src/sftp/testsuite/teardown-env lsh/src/sftp/werror.c lsh/src/sftp/werror.h lsh/src/sftp/xmalloc.c lsh/src/sftp/xmalloc.h lsh/src/sha.c lsh/src/sha.c.x lsh/src/spki.c lsh/src/spki.c.x lsh/src/spki.h lsh/src/spki.h.x lsh/src/spki_commands.c lsh/src/spki_commands.c.x lsh/src/spki_commands.h lsh/src/srp-gen.c lsh/src/srp-gen.c.x lsh/src/srp.h lsh/src/srp.h.x lsh/src/srp_exchange.c lsh/src/ssh-conv lsh/src/ssh.h lsh/src/ssh1_fallback.c lsh/src/ssh1_fallback.c.x lsh/src/ssh1_fallback.h lsh/src/ssh1_fallback.h.x lsh/src/string_buffer.c lsh/src/string_buffer.h lsh/src/suspend.c lsh/src/suspend.h lsh/src/tcpforward.c lsh/src/tcpforward.c.x lsh/src/tcpforward.h lsh/src/tcpforward.h.x lsh/src/tcpforward_commands.c lsh/src/tcpforward_commands.c.x lsh/src/tcpforward_commands.h lsh/src/testsuite/Makefile.am lsh/src/testsuite/Makefile.in lsh/src/testsuite/arcfour-test.c lsh/src/testsuite/arcfour-test.m4 lsh/src/testsuite/conv-1-test lsh/src/testsuite/conv-2-test lsh/src/testsuite/des-test.c lsh/src/testsuite/des-test.m4 lsh/src/testsuite/dsa-test.c lsh/src/testsuite/dsa-test.m4 lsh/src/testsuite/export-1-test lsh/src/testsuite/functions.sh lsh/src/testsuite/key-1.private lsh/src/testsuite/keygen-1-test lsh/src/testsuite/keygen-2-test lsh/src/testsuite/lsh-1-test lsh/src/testsuite/lsh-2-test lsh/src/testsuite/lsh-3-test lsh/src/testsuite/lsh-4-test lsh/src/testsuite/lsh-5-test lsh/src/testsuite/lsh-cat-test lsh/src/testsuite/lshg-cat-2-test lsh/src/testsuite/lshg-cat-test lsh/src/testsuite/lshg-tcpip-local-test lsh/src/testsuite/macros.m4 lsh/src/testsuite/md5-test.c lsh/src/testsuite/md5-test.m4 lsh/src/testsuite/rijndael-test.c lsh/src/testsuite/rijndael-test.m4 lsh/src/testsuite/rsa-test.c lsh/src/testsuite/rsa-test.m4 lsh/src/testsuite/runtests lsh/src/testsuite/sha1-test.c lsh/src/testsuite/sha1-test.m4 lsh/src/testsuite/spki-tag-test.c lsh/src/testsuite/spki-tag-test.m4 lsh/src/testsuite/ssh1-fallback-test lsh/src/testsuite/string-test.c lsh/src/testsuite/string-test.m4 lsh/src/testsuite/tcpip-local-test lsh/src/testsuite/tcpip-remote-test lsh/src/testsuite/twofish-test.c lsh/src/testsuite/twofish-test.m4 lsh/src/testsuite/write-key-1-test lsh/src/testsuite/write-key-2-test lsh/src/translate_signal.c lsh/src/translate_signal.h lsh/src/tty.c lsh/src/tty.h lsh/src/twofish.c lsh/src/twofish.c.x lsh/src/unix_interact.c lsh/src/unix_interact.c.x lsh/src/unix_random.c lsh/src/unix_random.c.x lsh/src/unix_user.c lsh/src/unix_user.c.x lsh/src/unpad.c lsh/src/unpad.c.x lsh/src/unpad.h lsh/src/userauth.c lsh/src/userauth.h lsh/src/userauth.h.x lsh/src/version.h lsh/src/werror.c lsh/src/werror.h lsh/src/write_buffer.c lsh/src/write_buffer.h lsh/src/write_buffer.h.x lsh/src/xalloc.c lsh/src/xalloc.h lsh/src/xauth.c lsh/src/xauth.h lsh/src/zlib.c lsh/src/zlib.c.x lsh/stamp-h.in zlib/ChangeLog zlib/FAQ zlib/INDEX zlib/MacOS/.cvsignore zlib/MacOS/zlib.CWPro6.mcp zlib/MacOS/zlib.CWPro7.mcp zlib/MacOS/zlib.mcp zlib/Make_vms.com zlib/Makefile.am zlib/Makefile.in zlib/Makefile.riscos zlib/README zlib/adler32.c zlib/algorithm.txt zlib/amiga/Makefile.pup zlib/amiga/Makefile.sas zlib/compress.c zlib/configure zlib/contrib/README.contrib zlib/contrib/asm386/gvmat32.asm zlib/contrib/asm386/gvmat32c.c zlib/contrib/asm386/mkgvmt32.bat zlib/contrib/asm386/zlibvc.def zlib/contrib/asm386/zlibvc.dsp zlib/contrib/asm386/zlibvc.dsw zlib/contrib/asm586/README.586 zlib/contrib/asm586/match.S zlib/contrib/asm686/README.686 zlib/contrib/asm686/match.S zlib/contrib/delphi/zlib.mak zlib/contrib/delphi/zlibdef.pas zlib/contrib/delphi2/d_zlib.bpr zlib/contrib/delphi2/d_zlib.cpp zlib/contrib/delphi2/readme.txt zlib/contrib/delphi2/zlib.bpg zlib/contrib/delphi2/zlib.bpr zlib/contrib/delphi2/zlib.cpp zlib/contrib/delphi2/zlib.pas zlib/contrib/delphi2/zlib32.bpr zlib/contrib/delphi2/zlib32.cpp zlib/contrib/iostream/test.cpp zlib/contrib/iostream/zfstream.cpp zlib/contrib/iostream/zfstream.h zlib/contrib/iostream2/zstream.h zlib/contrib/iostream2/zstream_test.cpp zlib/contrib/minizip/ChangeLogUnzip zlib/contrib/minizip/Makefile zlib/contrib/minizip/miniunz.c zlib/contrib/minizip/minizip.c zlib/contrib/minizip/readme.txt zlib/contrib/minizip/unzip.c zlib/contrib/minizip/unzip.def zlib/contrib/minizip/unzip.h zlib/contrib/minizip/zip.c zlib/contrib/minizip/zip.def zlib/contrib/minizip/zip.h zlib/contrib/minizip/zlibvc.def zlib/contrib/minizip/zlibvc.dsp zlib/contrib/minizip/zlibvc.dsw zlib/contrib/untgz/Makefile zlib/contrib/untgz/makefile.w32 zlib/contrib/untgz/untgz.c zlib/contrib/visual-basic.txt zlib/crc32.c zlib/deflate.c zlib/deflate.h zlib/descrip.mms zlib/example.c zlib/gzio.c zlib/infblock.c zlib/infblock.h zlib/infcodes.c zlib/infcodes.h zlib/inffast.c zlib/inffast.h zlib/inffixed.h zlib/inflate.c zlib/inftrees.c zlib/inftrees.h zlib/infutil.c zlib/infutil.h zlib/maketree.c zlib/minigzip.c zlib/msdos/Makefile.b32 zlib/msdos/Makefile.bor zlib/msdos/Makefile.dj2 zlib/msdos/Makefile.emx zlib/msdos/Makefile.msc zlib/msdos/Makefile.tc zlib/msdos/Makefile.w32 zlib/msdos/Makefile.wat zlib/msdos/zlib.def zlib/msdos/zlib.rc zlib/nt/Makefile.emx zlib/nt/Makefile.gcc zlib/nt/Makefile.nt zlib/nt/zlib.dnt zlib/os2/Makefile.os2 zlib/os2/zlib.def zlib/sshzlibrename.h zlib/trees.c zlib/trees.h zlib/uncompr.c zlib/zconf.h zlib/zlib.3 zlib/zlib.h zlib/zutil.c zlib/zutil.h
This commit is contained in:
parent
c7e41d1991
commit
4d0c119f40
|
@ -1,13 +0,0 @@
|
|||
# The "checkoutlist" file is used to support additional version controlled
|
||||
# administrative files in $CVSROOT/CVSROOT, such as template files.
|
||||
#
|
||||
# The first entry on a line is a filename which will be checked out from
|
||||
# the corresponding RCS file in the $CVSROOT/CVSROOT directory.
|
||||
# The remainder of the line is an error message to use if the file cannot
|
||||
# be checked out.
|
||||
#
|
||||
# File format:
|
||||
#
|
||||
# [<whitespace>]<filename><whitespace><error message><end-of-line>
|
||||
#
|
||||
# comment lines begin with '#'
|
|
@ -1,15 +0,0 @@
|
|||
# The "commitinfo" file is used to control pre-commit checks.
|
||||
# The filter on the right is invoked with the repository and a list
|
||||
# of files to check. A non-zero exit of the filter program will
|
||||
# cause the commit to be aborted.
|
||||
#
|
||||
# The first entry on a line is a regular expression which is tested
|
||||
# against the directory that the change is being committed to, relative
|
||||
# to the $CVSROOT. For the first match that is found, then the remainder
|
||||
# of the line is the name of the filter to run.
|
||||
#
|
||||
# If the repository name does not match any of the regular expressions in this
|
||||
# file, the "DEFAULT" line is used, if it is specified.
|
||||
#
|
||||
# If the name "ALL" appears as a regular expression it is always used
|
||||
# in addition to the first matching regex or "DEFAULT".
|
|
@ -1,11 +0,0 @@
|
|||
# Set this to "no" if pserver shouldn't check system users/passwords
|
||||
#SystemAuth=no
|
||||
|
||||
# Set `PreservePermissions' to `yes' to save file status information
|
||||
# in the repository.
|
||||
#PreservePermissions=no
|
||||
|
||||
# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top
|
||||
# level of the new working directory when using the `cvs checkout'
|
||||
# command.
|
||||
#TopLevelAdmin=no
|
|
@ -1,23 +0,0 @@
|
|||
# This file affects handling of files based on their names.
|
||||
#
|
||||
# The -t/-f options allow one to treat directories of files
|
||||
# as a single file, or to transform a file in other ways on
|
||||
# its way in and out of CVS.
|
||||
#
|
||||
# The -m option specifies whether CVS attempts to merge files.
|
||||
#
|
||||
# The -k option specifies keyword expansion (e.g. -kb for binary).
|
||||
#
|
||||
# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers)
|
||||
#
|
||||
# wildcard [option value][option value]...
|
||||
#
|
||||
# where option is one of
|
||||
# -f from cvs filter value: path to filter
|
||||
# -t to cvs filter value: path to filter
|
||||
# -m update methodology value: MERGE or COPY
|
||||
# -k expansion mode value: b, o, kkv, &c
|
||||
#
|
||||
# and value is a single-quote delimited value.
|
||||
# For example:
|
||||
#*.gif -k 'b'
|
|
@ -1,21 +0,0 @@
|
|||
# The "editinfo" file is used to allow verification of logging
|
||||
# information. It works best when a template (as specified in the
|
||||
# rcsinfo file) is provided for the logging procedure. Given a
|
||||
# template with locations for, a bug-id number, a list of people who
|
||||
# reviewed the code before it can be checked in, and an external
|
||||
# process to catalog the differences that were code reviewed, the
|
||||
# following test can be applied to the code:
|
||||
#
|
||||
# Making sure that the entered bug-id number is correct.
|
||||
# Validating that the code that was reviewed is indeed the code being
|
||||
# checked in (using the bug-id number or a seperate review
|
||||
# number to identify this particular code set.).
|
||||
#
|
||||
# If any of the above test failed, then the commit would be aborted.
|
||||
#
|
||||
# Actions such as mailing a copy of the report to each reviewer are
|
||||
# better handled by an entry in the loginfo file.
|
||||
#
|
||||
# One thing that should be noted is the the ALL keyword is not
|
||||
# supported. There can be only one entry that matches a given
|
||||
# repository.
|
|
@ -1,26 +0,0 @@
|
|||
# The "loginfo" file controls where "cvs commit" log information
|
||||
# is sent. The first entry on a line is a regular expression which must match
|
||||
# the directory that the change is being made to, relative to the
|
||||
# $CVSROOT. If a match is found, then the remainder of the line is a filter
|
||||
# program that should expect log information on its standard input.
|
||||
#
|
||||
# If the repository name does not match any of the regular expressions in this
|
||||
# file, the "DEFAULT" line is used, if it is specified.
|
||||
#
|
||||
# If the name ALL appears as a regular expression it is always used
|
||||
# in addition to the first matching regex or DEFAULT.
|
||||
#
|
||||
# You may specify a format string as part of the
|
||||
# filter. The string is composed of a `%' followed
|
||||
# by a single format character, or followed by a set of format
|
||||
# characters surrounded by `{' and `}' as separators. The format
|
||||
# characters are:
|
||||
#
|
||||
# s = file name
|
||||
# V = old version number (pre-checkin)
|
||||
# v = new version number (post-checkin)
|
||||
#
|
||||
# For example:
|
||||
#DEFAULT (echo ""; id; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog
|
||||
# or
|
||||
#DEFAULT (echo ""; id; echo %{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog
|
|
@ -1,29 +0,0 @@
|
|||
# Three different line formats are valid:
|
||||
# key -a aliases...
|
||||
# key [options] directory
|
||||
# key [options] directory files...
|
||||
#
|
||||
# Where "options" are composed of:
|
||||
# -i prog Run "prog" on "cvs commit" from top-level of module.
|
||||
# -o prog Run "prog" on "cvs checkout" of module.
|
||||
# -e prog Run "prog" on "cvs export" of module.
|
||||
# -t prog Run "prog" on "cvs rtag" of module.
|
||||
# -u prog Run "prog" on "cvs update" of module.
|
||||
# -d dir Place module in directory "dir" instead of module name.
|
||||
# -l Top-level directory only -- do not recurse.
|
||||
#
|
||||
# NOTE: If you change any of the "Run" options above, you'll have to
|
||||
# release and re-checkout any working directories of these modules.
|
||||
#
|
||||
# And "directory" is a path to a directory relative to $CVSROOT.
|
||||
#
|
||||
# The "-a" option specifies an alias. An alias is interpreted as if
|
||||
# everything on the right of the "-a" had been typed on the command line.
|
||||
#
|
||||
# You can encode a module within a module by using the special '&'
|
||||
# character to interpose another module into the current module. This
|
||||
# can be useful for creating a module that consists of many directories
|
||||
# spread out over the entire source repository.
|
||||
|
||||
MacSSH -a macssh lsh zlib gmp GUSI
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
# The "notify" file controls where notifications from watches set by
|
||||
# "cvs watch add" or "cvs edit" are sent. The first entry on a line is
|
||||
# a regular expression which is tested against the directory that the
|
||||
# change is being made to, relative to the $CVSROOT. If it matches,
|
||||
# then the remainder of the line is a filter program that should contain
|
||||
# one occurrence of %s for the user to notify, and information on its
|
||||
# standard input.
|
||||
#
|
||||
# "ALL" or "DEFAULT" can be used in place of the regular expression.
|
||||
#
|
||||
# For example:
|
||||
#ALL mail %s -s "CVS notification"
|
|
@ -1,13 +0,0 @@
|
|||
# The "rcsinfo" file is used to control templates with which the editor
|
||||
# is invoked on commit and import.
|
||||
#
|
||||
# The first entry on a line is a regular expression which is tested
|
||||
# against the directory that the change is being made to, relative to the
|
||||
# $CVSROOT. For the first match that is found, then the remainder of the
|
||||
# line is the name of the file that contains the template.
|
||||
#
|
||||
# If the repository name does not match any of the regular expressions in this
|
||||
# file, the "DEFAULT" line is used, if it is specified.
|
||||
#
|
||||
# If the name "ALL" appears as a regular expression it is always used
|
||||
# in addition to the first matching regex or "DEFAULT".
|
|
@ -1,20 +0,0 @@
|
|||
# The "taginfo" file is used to control pre-tag checks.
|
||||
# The filter on the right is invoked with the following arguments:
|
||||
#
|
||||
# $1 -- tagname
|
||||
# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d
|
||||
# $3 -- repository
|
||||
# $4-> file revision [file revision ...]
|
||||
#
|
||||
# A non-zero exit of the filter program will cause the tag to be aborted.
|
||||
#
|
||||
# The first entry on a line is a regular expression which is tested
|
||||
# against the directory that the change is being committed to, relative
|
||||
# to the $CVSROOT. For the first match that is found, then the remainder
|
||||
# of the line is the name of the filter to run.
|
||||
#
|
||||
# If the repository name does not match any of the regular expressions in this
|
||||
# file, the "DEFAULT" line is used, if it is specified.
|
||||
#
|
||||
# If the name "ALL" appears as a regular expression it is always used
|
||||
# in addition to the first matching regex or "DEFAULT".
|
|
@ -1,21 +0,0 @@
|
|||
# The "verifymsg" file is used to allow verification of logging
|
||||
# information. It works best when a template (as specified in the
|
||||
# rcsinfo file) is provided for the logging procedure. Given a
|
||||
# template with locations for, a bug-id number, a list of people who
|
||||
# reviewed the code before it can be checked in, and an external
|
||||
# process to catalog the differences that were code reviewed, the
|
||||
# following test can be applied to the code:
|
||||
#
|
||||
# Making sure that the entered bug-id number is correct.
|
||||
# Validating that the code that was reviewed is indeed the code being
|
||||
# checked in (using the bug-id number or a seperate review
|
||||
# number to identify this particular code set.).
|
||||
#
|
||||
# If any of the above test failed, then the commit would be aborted.
|
||||
#
|
||||
# Actions such as mailing a copy of the report to each reviewer are
|
||||
# better handled by an entry in the loginfo file.
|
||||
#
|
||||
# One thing that should be noted is the the ALL keyword is not
|
||||
# supported. There can be only one entry that matches a given
|
||||
# repository.
|
|
@ -1,51 +0,0 @@
|
|||
#ifndef _DCON_
|
||||
#define _DCON_
|
||||
|
||||
#include <MacTypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
void dopen(const char *log);
|
||||
void dprintf(const char *format,...);
|
||||
void vdprintf(const char *format,va_list arg);
|
||||
void dprintmem(const void *data,size_t len);
|
||||
|
||||
void dfprintf(const char *log,const char *format,...);
|
||||
void vdfprintf(const char *log,const char *format,va_list arg);
|
||||
void dfprintmem(const char *log,const void *data,size_t len);
|
||||
|
||||
|
||||
#ifndef DCON
|
||||
#define DCON 1
|
||||
#endif
|
||||
|
||||
#if DCON
|
||||
#define dAssertPrint(condition) dprintf(NULL,"Assert failed: " condition " %s:%d\n",__FILE__,__LINE__)
|
||||
#define dAssertIfTrue(condition) ((condition) ? dAssertPrint(#condition) : ((void)0))
|
||||
#define dAssertIfFalse(condition) ((condition) ? ((void)0) : dAssertPrint(#condition))
|
||||
#define dAssert(condition) dAssertIfFalse(condition)
|
||||
#else
|
||||
#define dAssertPrint(condition) ((void)0)
|
||||
#define dAssertIfTrue(condition) ((condition) ? ((void)0) : ((void)0))
|
||||
#define dAssertIfFalse(condition) ((condition) ? ((void)0) : ((void)0))
|
||||
#define dAssert(condition) dAssertIfFalse(condition)
|
||||
#define dopen while(0)
|
||||
#define dprintf while(0)
|
||||
#define vdprintf while(0)
|
||||
#define dprintmem while(0)
|
||||
#define dfprintf while(0)
|
||||
#define vfdprintf while(0)
|
||||
#define dfprintmem while(0)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _DCON_ */
|
|
@ -1,481 +0,0 @@
|
|||
/*********************************************************************
|
||||
File : GUSI - Grand Unified Socket Interface
|
||||
File : GUSIFileTest - Test plain files
|
||||
Author : Matthias Neeracher <neeri@iis.ethz.ch>
|
||||
Language : MPW C
|
||||
|
||||
$Log$
|
||||
Revision 1.1.1.1 2001/03/03 21:49:36 chombier
|
||||
Initial import
|
||||
|
||||
Revision 1.4 2000/05/23 06:38:53 neeri
|
||||
Added descriptor tests
|
||||
|
||||
Revision 1.3 2000/01/17 01:38:32 neeri
|
||||
Fix rename() directory separator handling
|
||||
|
||||
Revision 1.2 1999/04/10 04:24:53 neeri
|
||||
Reimplement ls and ll in a more standard way
|
||||
|
||||
Revision 1.1 1998/10/25 11:57:25 neeri
|
||||
Ready to release 2.0a3
|
||||
|
||||
Revision 1.2 1994/12/31 01:10:41 neeri
|
||||
ANSIfy.
|
||||
Test FSSpec encoding.
|
||||
|
||||
Revision 1.1 1994/02/25 02:46:54 neeri
|
||||
Initial revision
|
||||
|
||||
Revision 0.9 1993/07/29 00:00:00 neeri
|
||||
scandir
|
||||
|
||||
Revision 0.8 1993/07/18 00:00:00 neeri
|
||||
dirent -> struct dirent
|
||||
|
||||
Revision 0.7 1992/12/20 00:00:00 neeri
|
||||
Allow defaults for choose()
|
||||
|
||||
Revision 0.6 1992/12/08 00:00:00 neeri
|
||||
Pwd()
|
||||
|
||||
Revision 0.5 1992/10/27 00:00:00 neeri
|
||||
Forgot to adapt it to dirent.h
|
||||
|
||||
Revision 0.4 1992/09/07 00:00:00 neeri
|
||||
RdLink()
|
||||
|
||||
Revision 0.3 1992/07/25 00:00:00 neeri
|
||||
Isolated testing gear in GUSITest
|
||||
|
||||
Revision 0.2 1992/07/13 00:00:00 neeri
|
||||
Test choose()
|
||||
|
||||
Revision 0.1 1992/06/14 00:00:00 neeri
|
||||
More tests
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#include "GUSITest.h"
|
||||
#include "GUSIFileSpec.h"
|
||||
#include <Types.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
void Stat(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
int res;
|
||||
struct stat statbuf;
|
||||
char filename[80];
|
||||
|
||||
if (sscanf(cmd, "%s", filename) != 1)
|
||||
Usage(ch1, ch2);
|
||||
else {
|
||||
if (ch2 == 'l') {
|
||||
cmd = "lstat";
|
||||
res = lstat(filename, &statbuf);
|
||||
} else {
|
||||
cmd = "stat";
|
||||
res = stat(filename, &statbuf);
|
||||
}
|
||||
|
||||
if (res) {
|
||||
printf("# %s(\"%s\") returned error %s\n", cmd, filename, Explain());
|
||||
} else {
|
||||
printf("# %s(\"%s\") =\n", cmd, filename);
|
||||
DUMP(statbuf.st_dev,d);
|
||||
DUMP(statbuf.st_ino,d);
|
||||
DUMP(statbuf.st_mode,o);
|
||||
DUMP(statbuf.st_nlink,d);
|
||||
DUMP(statbuf.st_uid,d);
|
||||
DUMP(statbuf.st_gid,d);
|
||||
DUMP(statbuf.st_rdev,d);
|
||||
DUMP(statbuf.st_size,d);
|
||||
DUMP(statbuf.st_atime,u);
|
||||
DUMP(statbuf.st_mtime,u);
|
||||
DUMP(statbuf.st_ctime,u);
|
||||
DUMP(statbuf.st_blksize,d);
|
||||
DUMP(statbuf.st_blocks,d);
|
||||
}
|
||||
Where();
|
||||
}
|
||||
}
|
||||
|
||||
void ChDir(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
char directory[80];
|
||||
|
||||
if (sscanf(cmd, "%s", directory) != 1)
|
||||
Usage(ch1, ch2);
|
||||
else if (chdir(directory)) {
|
||||
printf("# chdir(\"%s\") returned error %s\n", directory, Explain());
|
||||
Where();
|
||||
}
|
||||
}
|
||||
|
||||
void MkDir(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
char directory[80];
|
||||
|
||||
if (sscanf(cmd, "%s", directory) != 1)
|
||||
Usage(ch1, ch2);
|
||||
else if (mkdir(directory)) {
|
||||
printf("# mkdir(\"%s\") returned error %s\n", directory, Explain());
|
||||
Where();
|
||||
}
|
||||
}
|
||||
|
||||
void RmDir(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
char directory[80];
|
||||
|
||||
if (sscanf(cmd, "%s", directory) != 1)
|
||||
Usage(ch1, ch2);
|
||||
else if (rmdir(directory)) {
|
||||
printf("# rmdir(\"%s\") returned error %s\n", directory, Explain());
|
||||
Where();
|
||||
}
|
||||
}
|
||||
|
||||
void List(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
int count;
|
||||
int i;
|
||||
DIR * dir;
|
||||
struct dirent * entry;
|
||||
char * dirend;
|
||||
char directory[80];
|
||||
struct stat statbuf;
|
||||
|
||||
if (sscanf(cmd, "%s", directory) != 1)
|
||||
strcpy(directory, ":");
|
||||
|
||||
if (ch2 == 'l' && !strchr(directory, ':')) {
|
||||
directory[0] = ':';
|
||||
sscanf(cmd, "%s", directory+1);
|
||||
}
|
||||
|
||||
if (!(dir = opendir(directory))) {
|
||||
printf("# opendir(\"%s\") returned error %s\n", directory, Explain());
|
||||
goto error;
|
||||
}
|
||||
|
||||
printf("# directory \"%s\" =\n", directory);
|
||||
|
||||
dirend = directory + strlen(directory);
|
||||
if (dirend[-1] != ':')
|
||||
*dirend++ = ':';
|
||||
|
||||
while (entry = readdir(dir))
|
||||
if (ch2 == 's')
|
||||
printf("# %s\n", entry->d_name);
|
||||
else {
|
||||
strcpy(dirend, entry->d_name);
|
||||
|
||||
if (lstat(directory, &statbuf))
|
||||
printf("# lstat(\"%s\") returned error %s\n", entry->d_name, Explain());
|
||||
else
|
||||
printf("# %c %7d %s\n",
|
||||
(statbuf.st_mode & S_IFMT) == S_IFREG ? 'F' :
|
||||
(statbuf.st_mode & S_IFMT) == S_IFDIR ? 'D' :
|
||||
(statbuf.st_mode & S_IFMT) == S_IFLNK ? 'L' : '?',
|
||||
statbuf.st_size,
|
||||
entry->d_name);
|
||||
}
|
||||
closedir(dir);
|
||||
|
||||
error:
|
||||
Where();
|
||||
}
|
||||
|
||||
void Type(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
FILE * fl;
|
||||
char line[500];
|
||||
char filename[80];
|
||||
|
||||
if (sscanf(cmd, "%s", filename) != 1)
|
||||
Usage(ch1, ch2);
|
||||
else {
|
||||
fl = fopen(filename, "r");
|
||||
|
||||
if (!fl)
|
||||
printf("# open(\"%s\") returned error %s\n", filename, Explain());
|
||||
else {
|
||||
printf("# \"%s\" =\n", filename);
|
||||
while (fgets(line, 500, fl))
|
||||
fputs(line, stdout);
|
||||
|
||||
fclose(fl);
|
||||
}
|
||||
|
||||
|
||||
Where();
|
||||
}
|
||||
}
|
||||
|
||||
void Encode(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
#if 0
|
||||
OSErr err;
|
||||
char filename[80];
|
||||
|
||||
if (sscanf(cmd, "%s", filename) != 1)
|
||||
Usage(ch1, ch2);
|
||||
else {
|
||||
FSSpec spec;
|
||||
|
||||
if (err = Path2FSSpec(filename, &spec))
|
||||
fprintf(stderr, "Path2FSSpec(%s) returned error %d\n", filename, err);
|
||||
else
|
||||
fprintf(stderr, "%s -> %s\n", filename, FSp2Encoding(&spec));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Glob(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
#if 0
|
||||
OSErr err;
|
||||
FileGlobRef glob;
|
||||
char filename[80];
|
||||
|
||||
if (sscanf(cmd, "%s", filename) != 1)
|
||||
Usage(ch1, ch2);
|
||||
else if (!(glob = NewFileGlob(filename)))
|
||||
fprintf(stderr, "NewFileGlob(%s) failed.\n", filename);
|
||||
else {
|
||||
FSSpec spec;
|
||||
|
||||
fprintf(stderr, "Glob(%s) matched:\n", filename);
|
||||
while (FileGlob2FSSpec(glob, &spec)) {
|
||||
fprintf(stderr, " %s\n", FSp2FullPath(&spec));
|
||||
NextFileGlob(glob);
|
||||
}
|
||||
DisposeFileGlob(glob);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Edit(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
FILE * fl;
|
||||
char line[500];
|
||||
char filename[80];
|
||||
|
||||
if (sscanf(cmd, "%s", filename) != 1)
|
||||
Usage(ch1, ch2);
|
||||
else {
|
||||
fl = fopen(filename, "w");
|
||||
|
||||
if (!fl)
|
||||
printf("# open(\"%s\") returned error %s\n", filename, Explain());
|
||||
else {
|
||||
printf("# Enter \"%s\", terminate with \".\"\n", filename);
|
||||
while (fgets(line, 500, stdin))
|
||||
if (strcmp(line, ".\n"))
|
||||
fputs(line, fl);
|
||||
else
|
||||
break;
|
||||
|
||||
fclose(fl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Rm(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
char filename[80];
|
||||
|
||||
if (sscanf(cmd, "%s", filename) != 1)
|
||||
Usage(ch1, ch2);
|
||||
else if (remove(filename)) {
|
||||
printf("# remove(\"%s\") returned error %s\n", filename, Explain());
|
||||
Where();
|
||||
}
|
||||
}
|
||||
|
||||
void Mv(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
struct stat statbuf;
|
||||
char oldfilename[80];
|
||||
char newfilename[80];
|
||||
|
||||
if (sscanf(cmd, "%s %s", oldfilename, newfilename) != 2)
|
||||
Usage(ch1, ch2);
|
||||
else {
|
||||
if (!stat(newfilename, &statbuf) && (statbuf.st_mode & S_IFMT) == S_IFDIR) {
|
||||
char * fn;
|
||||
char * next;
|
||||
int len = strlen(newfilename);
|
||||
|
||||
/* Extract file name part from oldfilename */
|
||||
for (fn = oldfilename; (next = strchr(fn, ':')) && next[1]; fn = next+1);
|
||||
|
||||
if (!strchr(newfilename, ':')) { /* Prepend ':' if necessary */
|
||||
newfilename[0] = ':';
|
||||
sscanf(cmd, "%s %s", oldfilename, newfilename+1);
|
||||
++len;
|
||||
}
|
||||
|
||||
if (newfilename[len-1] != ':')
|
||||
newfilename[len++] = ':';
|
||||
|
||||
strcpy(newfilename+len, fn);
|
||||
}
|
||||
|
||||
if (rename(oldfilename, newfilename)) {
|
||||
printf("# rename(\"%s\", \"%s\") returned error %s\n", oldfilename, newfilename, Explain());
|
||||
Where();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Link(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
char oldfilename[80];
|
||||
char newfilename[80];
|
||||
|
||||
if (sscanf(cmd, "%s %s", oldfilename, newfilename) != 2)
|
||||
Usage(ch1, ch2);
|
||||
else {
|
||||
if (symlink(oldfilename, newfilename)) {
|
||||
printf("# symlink(\"%s\", \"%s\") returned error %s\n", oldfilename, newfilename, Explain());
|
||||
Where();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RdLink(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
char path[200];
|
||||
char link[200];
|
||||
int len;
|
||||
|
||||
if (sscanf(cmd, "%s", path) != 1)
|
||||
Usage(ch1, ch2);
|
||||
|
||||
len = readlink(path, link, 199);
|
||||
|
||||
if (len < 0)
|
||||
printf("# readlink(\"%s\") returned error %s\n", path, Explain());
|
||||
else {
|
||||
link[len] = 0;
|
||||
printf("# readlink(\"%s\") returned \"%s\"\n", path, link);
|
||||
}
|
||||
|
||||
Where();
|
||||
}
|
||||
|
||||
void Pwd(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
char * buf;
|
||||
|
||||
buf = getcwd(NULL, 1024);
|
||||
|
||||
if (!buf)
|
||||
printf("# getcwd() returned error %s\n", Explain());
|
||||
else {
|
||||
printf("# getcwd() returned \"%s\"\n", buf);
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
Where();
|
||||
}
|
||||
|
||||
void Access(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
char filename[80];
|
||||
|
||||
if (sscanf(cmd, "%s", filename) != 1)
|
||||
Usage(ch1, ch2);
|
||||
else {
|
||||
if (access(filename, F_OK))
|
||||
printf("# access(\"%s\", F_OK) returned error %s\n", filename, Explain());
|
||||
else
|
||||
printf("# access(\"%s\", F_OK) succeeded.\n", filename, Explain());
|
||||
if (access(filename, R_OK))
|
||||
printf("# access(\"%s\", R_OK) returned error %s\n", filename, Explain());
|
||||
else
|
||||
printf("# access(\"%s\", R_OK) succeeded.\n", filename, Explain());
|
||||
if (access(filename, W_OK))
|
||||
printf("# access(\"%s\", W_OK) returned error %s\n", filename, Explain());
|
||||
else
|
||||
printf("# access(\"%s\", W_OK) succeeded.\n", filename, Explain());
|
||||
if (access(filename, X_OK))
|
||||
printf("# access(\"%s\", X_OK) returned error %s\n", filename, Explain());
|
||||
else
|
||||
printf("# access(\"%s\", X_OK) succeeded.\n", filename, Explain());
|
||||
Where();
|
||||
}
|
||||
}
|
||||
|
||||
void Open(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
char filename[80];
|
||||
|
||||
if (sscanf(cmd, "%s", filename) != 1)
|
||||
Usage(ch1, ch2);
|
||||
else if ((sock = open(filename, O_RDONLY)) < 0)
|
||||
printf("# open(\"%s\") returned error %s\n", filename, Explain());
|
||||
}
|
||||
|
||||
void Seek(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
int whence;
|
||||
int offset;
|
||||
int result;
|
||||
|
||||
if (sock == -1) {
|
||||
printf("# socket is not open\n");
|
||||
Where();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (sscanf(cmd, "%d %d", &offset, &whence) != 2) {
|
||||
Usage(ch1, ch2);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((result = lseek(sock, offset, whence)) < 0)
|
||||
printf("# lseek(%d %d) returned error %s\n", offset, whence, Explain());
|
||||
else
|
||||
printf("# lseek(%d %d) ended up at offset %d\n", offset, whence, result);
|
||||
}
|
||||
|
||||
main(int argc, char ** argv)
|
||||
{
|
||||
printf("GUSIFileTest MN 21May00\n\n");
|
||||
|
||||
AddDescriptorCommands();
|
||||
|
||||
COMMAND('s', 't', Stat, "filename", "Call stat() on a file");
|
||||
COMMAND('s', 'l', Stat, "filename", "Call lstat() on a file");
|
||||
COMMAND('c', 'd', ChDir, "directory", "Call chdir()");
|
||||
COMMAND('l', 's', List, "[ directory ]", "List a directory");
|
||||
COMMAND('l', 'l', List, "[ directory ]", "List a directory with more info");
|
||||
COMMAND('m', 'd', MkDir, "directory", "Make a new directory");
|
||||
COMMAND('d', 'd', RmDir, "directory", "Delete an empty directory");
|
||||
COMMAND('t', 'y', Type, "filename", "Type out the contents of a file");
|
||||
COMMAND('e', 'd', Edit, "filename", "Enter the contents of a new file");
|
||||
COMMAND('m', 'v', Mv, "oldfile newfile", "Rename/Move a file");
|
||||
COMMAND('r', 'm', Rm, "filename", "Delete a file");
|
||||
COMMAND('r', 'l', RdLink,"filename", "Read symbolic link");
|
||||
COMMAND('l', 'n', Link, "oldfile newfile", "Create a symbolic link");
|
||||
COMMAND('p', 'w', Pwd, "", "Print current directory");
|
||||
COMMAND('e', 'n', Encode,"filename", "Translate filename to encoded FSSpec");
|
||||
COMMAND('g', 'l', Glob, "filename", "Expand wildcards");
|
||||
COMMAND('a', 'c', Access,"filename", "Test access rights");
|
||||
COMMAND('o', 'p', Open, "filename", "Open a file (to test commands on open files)");
|
||||
COMMAND('s', 'k', Seek, "offset whence", "Seek on open descriptor");
|
||||
RunTest(argc, argv);
|
||||
}
|
|
@ -1,601 +0,0 @@
|
|||
/*********************************************************************
|
||||
Project : GUSI - Grand Unified Socket Interface
|
||||
File : GUSIINETTest - Test unix domain sockets
|
||||
Author : Matthias Neeracher <neeri@iis.ethz.ch>
|
||||
Language : MPW C
|
||||
|
||||
$Log$
|
||||
Revision 1.1.1.1 2001/03/03 21:49:39 chombier
|
||||
Initial import
|
||||
|
||||
Revision 1.4 2000/10/15 21:49:20 neeri
|
||||
Add multiple connection test
|
||||
|
||||
Revision 1.3 2000/05/23 06:40:03 neeri
|
||||
Add Linger, Getsockname tests
|
||||
|
||||
Revision 1.2 2000/03/06 08:28:32 neeri
|
||||
Releasing 2.0.5
|
||||
|
||||
Revision 1.1 1998/10/25 11:57:26 neeri
|
||||
Ready to release 2.0a3
|
||||
|
||||
Revision 1.1 1994/12/31 00:50:27 neeri
|
||||
Initial revision
|
||||
|
||||
Revision 0.6 1993/08/25 00:00:00 neeri
|
||||
gethostbyaddr()
|
||||
|
||||
Revision 0.5 1993/07/29 00:00:00 neeri
|
||||
servent tests
|
||||
|
||||
Revision 0.4 1993/03/03 00:00:00 neeri
|
||||
Added performance test
|
||||
|
||||
Revision 0.3 1992/09/14 00:00:00 neeri
|
||||
Misinterpreted hostent structure
|
||||
|
||||
Revision 0.2 1992/09/08 00:00:00 neeri
|
||||
Factor out common socket routines
|
||||
|
||||
Revision 0.1 1992/09/08 00:00:00 neeri
|
||||
First attempt
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#include "GUSITest.h"
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/time.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Events.h"
|
||||
|
||||
char addrstr[100];
|
||||
|
||||
void Socket(char ch1, char ch2, const char * line)
|
||||
{
|
||||
sock = socket(AF_INET, (ch1 == 's') ? SOCK_STREAM : SOCK_DGRAM, 0);
|
||||
|
||||
if (sock == -1) {
|
||||
printf("# socket() returned error %d [%s]\n", errno, Explain());
|
||||
Where();
|
||||
}
|
||||
}
|
||||
|
||||
void Bind(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
int len;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
if (sock == -1) {
|
||||
printf("# socket is not open\n");
|
||||
Where();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (sscanf(cmd, "%s %hd", addrstr, &addr.sin_port) == 2) {
|
||||
addr.sin_addr.s_addr = inet_addr(addrstr);
|
||||
addr.sin_family = AF_INET;
|
||||
len = sizeof(struct sockaddr_in);
|
||||
} else {
|
||||
Usage(ch1, ch2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bind(sock, (struct sockaddr *) &addr, len)) {
|
||||
printf(
|
||||
"bind(%s:%d) returned error %d [%s]\n",
|
||||
inet_ntoa(addr.sin_addr),
|
||||
addr.sin_port,
|
||||
errno, Explain());
|
||||
|
||||
Where();
|
||||
}
|
||||
}
|
||||
|
||||
void NoDelay(char , char , const char * cmd)
|
||||
{
|
||||
int one = 1;
|
||||
|
||||
if (sock == -1) {
|
||||
printf("# socket is not open\n");
|
||||
Where();
|
||||
return;
|
||||
}
|
||||
|
||||
if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof(int)))
|
||||
printf(
|
||||
"setsockopt(IPPROTO_TCP, TCP_NODELAY) returned error %d [%s]\n",
|
||||
errno, Explain());
|
||||
}
|
||||
|
||||
void Linger(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
struct linger l;
|
||||
|
||||
if (sock == -1) {
|
||||
printf("# socket is not open\n");
|
||||
Where();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (sscanf(cmd, "%d", &l.l_linger) == 1) {
|
||||
l.l_onoff = l.l_linger > -1;
|
||||
} else {
|
||||
Usage(ch1, ch2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_LINGER, (char*)&l, sizeof(struct linger)))
|
||||
printf(
|
||||
"setsockopt(SOL_SOCKET, SO_LINGER) returned error %d [%s]\n",
|
||||
errno, Explain());
|
||||
}
|
||||
|
||||
void Accept(char ch1, char ch2, const char * line)
|
||||
{
|
||||
socklen_t len;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
if (sock == -1) {
|
||||
printf("# socket is not open\n");
|
||||
Where();
|
||||
|
||||
return;
|
||||
}
|
||||
if (accsock != -1) {
|
||||
printf("# can't accept more than one connection\n");
|
||||
Where();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
len = sizeof(struct sockaddr_in);
|
||||
sock = accept(accsock = sock, (struct sockaddr *) &addr, &len);
|
||||
|
||||
if (sock < 0) {
|
||||
printf("# accept() returned error %d [%s]\n", errno, Explain());
|
||||
sock = accsock;
|
||||
accsock = -1;
|
||||
} else {
|
||||
printf(
|
||||
"# accepted connection from %s port %d\n",
|
||||
inet_ntoa(addr.sin_addr),
|
||||
addr.sin_port);
|
||||
}
|
||||
|
||||
Where();
|
||||
}
|
||||
|
||||
void Getsockname(char ch1, char ch2, const char * line)
|
||||
{
|
||||
socklen_t len;
|
||||
struct sockaddr_in addr;
|
||||
int err;
|
||||
|
||||
if (sock == -1) {
|
||||
printf("# socket is not open\n");
|
||||
Where();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
len = sizeof(struct sockaddr_in);
|
||||
|
||||
if (ch2 == 's')
|
||||
err = getsockname(accsock = sock, (struct sockaddr *) &addr, &len);
|
||||
else
|
||||
err = getpeername(accsock = sock, (struct sockaddr *) &addr, &len);
|
||||
if (err < 0) {
|
||||
printf("# get%sname() returned error %d [%s]\n",
|
||||
(ch2 == 's' ? "sock" : "peer"), errno, Explain());
|
||||
} else {
|
||||
printf(
|
||||
"# %s are %s port %d\n", (ch2 == 's' ? "We" : "They"),
|
||||
inet_ntoa(addr.sin_addr),
|
||||
addr.sin_port);
|
||||
}
|
||||
|
||||
Where();
|
||||
}
|
||||
|
||||
void Connect(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
int len;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
if (sock == -1) {
|
||||
printf("# socket is not open\n");
|
||||
Where();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (sscanf(cmd, "%s %hd", addrstr, &addr.sin_port) == 2) {
|
||||
addr.sin_addr.s_addr = inet_addr(addrstr);
|
||||
addr.sin_family = AF_INET;
|
||||
len = sizeof(struct sockaddr_in);
|
||||
} else {
|
||||
Usage(ch1, ch2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (connect(sock, (struct sockaddr *) &addr, len)) {
|
||||
printf(
|
||||
"connect(%s:%d) returned error %s\n",
|
||||
inet_ntoa(addr.sin_addr),
|
||||
addr.sin_port,
|
||||
Explain());
|
||||
Where();
|
||||
}
|
||||
}
|
||||
|
||||
static int sSock[1000];
|
||||
static int sSockUsed;
|
||||
|
||||
void MultiConn(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
int len;
|
||||
int count;
|
||||
int i;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
if (sscanf(cmd, "%d %s %hd", &count, addrstr, &addr.sin_port) == 3) {
|
||||
addr.sin_addr.s_addr = inet_addr(addrstr);
|
||||
addr.sin_family = AF_INET;
|
||||
len = sizeof(struct sockaddr_in);
|
||||
} else {
|
||||
Usage(ch1, ch2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (count > 1000-sSockUsed)
|
||||
count = 1000-sSockUsed;
|
||||
for (i=0; i<count; ++i) {
|
||||
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (connect(sock, (struct sockaddr *) &addr, len)) {
|
||||
printf(
|
||||
"#%d: connect(%s:%d) returned error %s\n",
|
||||
i,
|
||||
inet_ntoa(addr.sin_addr),
|
||||
addr.sin_port,
|
||||
Explain());
|
||||
Where();
|
||||
close(sock);
|
||||
if (!i)
|
||||
break;
|
||||
} else {
|
||||
struct sockaddr_in addr;
|
||||
socklen_t len;
|
||||
|
||||
len = sizeof(struct sockaddr_in);
|
||||
getsockname(sock, (struct sockaddr *) &addr, &len);
|
||||
printf("#%d connected from port %d\n", i, addr.sin_port);
|
||||
sSock[sSockUsed++] = sock;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MultiDis(char, char, const char * cmd)
|
||||
{
|
||||
while (sSockUsed > 0)
|
||||
close(sSock[--sSockUsed]);
|
||||
}
|
||||
|
||||
int ReadWhileUCan()
|
||||
{
|
||||
int res;
|
||||
char * outline;
|
||||
fd_set rdfds;
|
||||
fd_set exfds;
|
||||
struct timeval delay;
|
||||
char out[500];
|
||||
|
||||
for (;;) {
|
||||
FD_ZERO(&rdfds);
|
||||
FD_ZERO(&exfds);
|
||||
|
||||
FD_SET(sock, &rdfds);
|
||||
FD_SET(sock, &exfds);
|
||||
|
||||
delay.tv_sec = 1;
|
||||
delay.tv_usec = 0;
|
||||
|
||||
res = select(sock+1, &rdfds, nil, &exfds, &delay);
|
||||
|
||||
if (res < 0) {
|
||||
printf("# select() returned error %d [%s]\n", errno, Explain());
|
||||
|
||||
return -1;
|
||||
} else if (!res)
|
||||
return 0;
|
||||
else if (res && FD_ISSET(sock, &exfds)) {
|
||||
printf("# select() returned an exception\n");
|
||||
|
||||
return -1;
|
||||
} else if (res && FD_ISSET(sock, &rdfds)) {
|
||||
res = read(sock, out, 500);
|
||||
|
||||
if (res < 0) {
|
||||
printf("# read() returned error %d [%s]\n", errno, Explain());
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
out[res] = 0;
|
||||
|
||||
for (outline = strtok(out, "\n\r"); outline; outline = strtok(nil, "\n\r"))
|
||||
printf("%s\n", outline);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Telnet(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
int len;
|
||||
int part;
|
||||
int res;
|
||||
char * line;
|
||||
char * outline;
|
||||
fd_set rdfds;
|
||||
fd_set wrfds;
|
||||
fd_set exfds;
|
||||
struct timeval delay;
|
||||
char in[100];
|
||||
char out[500];
|
||||
|
||||
if (sock == -1) {
|
||||
printf("# socket is not open\n");
|
||||
Where();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
printf("# Entering Poor Man's Telnet mode\n");
|
||||
|
||||
for (;;) {
|
||||
if (ReadWhileUCan())
|
||||
break;
|
||||
|
||||
Prompt();
|
||||
|
||||
if (!fgets(in, 100, input))
|
||||
break;
|
||||
|
||||
++inputline;
|
||||
|
||||
if (!strcmp(in, ".\n"))
|
||||
break;
|
||||
|
||||
if (!strcmp(in, "?\n"))
|
||||
continue;
|
||||
|
||||
len = strlen(in);
|
||||
in[len++] = '\r';
|
||||
in[len] = 0;
|
||||
|
||||
for (line = in; len; len -= part, line += part) {
|
||||
part = 0;
|
||||
|
||||
FD_ZERO(&rdfds);
|
||||
FD_ZERO(&wrfds);
|
||||
FD_ZERO(&exfds);
|
||||
|
||||
FD_SET(sock, &rdfds);
|
||||
FD_SET(sock, &wrfds);
|
||||
FD_SET(sock, &exfds);
|
||||
|
||||
delay.tv_sec = 10;
|
||||
delay.tv_usec = 0;
|
||||
|
||||
res = select(sock+1, &rdfds, &wrfds, &exfds, &delay);
|
||||
|
||||
if (res < 0) {
|
||||
printf("# select() returned error %d [%s]\n", errno, Explain());
|
||||
|
||||
return;
|
||||
} else if (!res) {
|
||||
printf("# select() timed out\n");
|
||||
|
||||
return;
|
||||
} else if (FD_ISSET(sock, &exfds)) {
|
||||
printf("# select() returned an exception\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (FD_ISSET(sock, &rdfds)) {
|
||||
res = read(sock, out, 500);
|
||||
|
||||
if (res < 0) {
|
||||
printf("# read() returned error %d [%s]\n", errno, Explain());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
out[res] = 0;
|
||||
|
||||
for (outline = strtok(out, "\n\r"); outline; outline = strtok(nil, "\n\r"))
|
||||
printf("%s\n", outline);
|
||||
} else if (FD_ISSET(sock, &wrfds)) {
|
||||
res = write(sock, line, len);
|
||||
|
||||
if (res < 0) {
|
||||
line[strlen(line) - 2] = 0;
|
||||
printf("# write(\"%s\") returned error %s\n", line, Explain());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
part = res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("# Leaving Poor Man's Telnet mode\n");
|
||||
}
|
||||
|
||||
void N2Addr(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
struct in_addr addr;
|
||||
struct hostent * ent;
|
||||
|
||||
if (sscanf(cmd, "%s", addrstr) == 1)
|
||||
if (ent = gethostbyname(addrstr)) {
|
||||
memcpy(&addr, ent->h_addr, sizeof(struct in_addr));
|
||||
printf("# gethostbyname(%s) returned %s\n", addrstr, inet_ntoa(addr));
|
||||
} else
|
||||
printf("# gethostbyname(%s) failed.\n", addrstr);
|
||||
else
|
||||
Usage(ch1, ch2);
|
||||
}
|
||||
|
||||
void A2Name(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
in_addr_t addr;
|
||||
struct hostent * ent;
|
||||
|
||||
if (sscanf(cmd, "%s", addrstr) == 1) {
|
||||
addr = inet_addr(addrstr);
|
||||
if (ent = gethostbyaddr((char *) &addr, 0, 0)) {
|
||||
printf("# gethostbyaddr(%s) returned %s\n", addrstr, ent->h_name);
|
||||
} else
|
||||
printf("# gethostbyaddr(%s) failed.\n", addrstr);
|
||||
} else
|
||||
Usage(ch1, ch2);
|
||||
}
|
||||
|
||||
void PerfTest(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
int count;
|
||||
int i;
|
||||
long ticks;
|
||||
char buf[1024];
|
||||
|
||||
if (sock == -1) {
|
||||
printf("# socket is not open\n");
|
||||
Where();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (sscanf(cmd, "%d", &count) == 1) {
|
||||
ticks = TickCount();
|
||||
for (i=0; i<count; i++) {
|
||||
write(sock, buf, 1);
|
||||
read(sock, buf, 1024);
|
||||
}
|
||||
printf("# Did %d iterations in %d ticks.\n", count, TickCount()-ticks);
|
||||
} else
|
||||
Usage(ch1, ch2);
|
||||
}
|
||||
|
||||
void ServByName(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
struct servent * ent;
|
||||
char proto[6];
|
||||
|
||||
if (sscanf(cmd, "%s %s", addrstr, proto) == 2)
|
||||
if (ent = getservbyname(addrstr, proto))
|
||||
printf("# getservbyname(%s %s) returned %d\n", addrstr, proto, ent->s_port);
|
||||
else
|
||||
printf("# getservbyname(%s %s) failed.\n", addrstr, proto);
|
||||
else if (sscanf(cmd, "%s", addrstr) == 1)
|
||||
if (ent = getservbyname(addrstr, NULL))
|
||||
printf("# getservbyname(%s) returned %d\n", addrstr, ent->s_port);
|
||||
else
|
||||
printf("# getservbyname(%s) failed.\n", addrstr);
|
||||
else
|
||||
Usage(ch1, ch2);
|
||||
}
|
||||
|
||||
void PrintServEnt(struct servent * ent, Boolean full)
|
||||
{
|
||||
char ** al;
|
||||
|
||||
printf("%s", ent->s_name);
|
||||
|
||||
if (full)
|
||||
printf(" %d/%s", ent->s_port, ent->s_proto);
|
||||
|
||||
for (al = ent->s_aliases; *al; ++al)
|
||||
printf(" %s", *al);
|
||||
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
void ServByPort(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
int port;
|
||||
struct servent * ent;
|
||||
char proto[6];
|
||||
|
||||
if (sscanf(cmd, "%d %s", &port, proto) == 2)
|
||||
if (ent = getservbyport(port, proto)) {
|
||||
printf("# getservbyport(%d %s) returned ", port, proto);
|
||||
|
||||
PrintServEnt(ent, false);
|
||||
} else
|
||||
printf("# getservbyport(%d %s) failed.\n", addrstr, proto);
|
||||
else if (sscanf(cmd, "%d %s", &port) == 1)
|
||||
if (ent = getservbyport(port, NULL)) {
|
||||
printf("# getservbyport(%d) returned ", port);
|
||||
|
||||
PrintServEnt(ent, false);
|
||||
} else
|
||||
printf("# getservbyport(%d) failed.\n", addrstr);
|
||||
else
|
||||
Usage(ch1, ch2);
|
||||
}
|
||||
|
||||
void ServList(char ch1, char ch2, const char * line)
|
||||
{
|
||||
struct servent * ent;
|
||||
|
||||
setservent(0);
|
||||
|
||||
while (ent = getservent()) {
|
||||
printf("# ");
|
||||
PrintServEnt(ent, true);
|
||||
}
|
||||
}
|
||||
|
||||
main(int argc, char ** argv)
|
||||
{
|
||||
printf("GUSIINETTest MN 14May00\n\n");
|
||||
|
||||
COMMAND('s', 's', Socket, "", "Create a stream socket");
|
||||
COMMAND('d', 's', Socket, "", "Create a datagram socket");
|
||||
COMMAND('b', 'd', Bind, "addr port", "Bind to address");
|
||||
COMMAND('c', 'o', Connect, "addr port", "Connect to address");
|
||||
COMMAND('m', 'c', MultiConn, "# addr port", "Connect multiple times to address");
|
||||
COMMAND('m', 'd', MultiDis, "", "Disconnect the connections");
|
||||
COMMAND('a', 'c', Accept, "", "Accept a connection");
|
||||
COMMAND('t', 'n', Telnet, "", "Play telnet");
|
||||
COMMAND('n', 'a', N2Addr, "name", "Convert name to address");
|
||||
COMMAND('a', 'n', A2Name, "addr", "Convert address to name");
|
||||
COMMAND('p', 't', PerfTest,"count", "Do a performance test");
|
||||
COMMAND('s', 'n', ServByName, "name", "Convert service name to port number");
|
||||
COMMAND('s', 'p', ServByPort, "port", "Convert port number to service name");
|
||||
COMMAND('s', 'l', ServList, "", "List services");
|
||||
COMMAND('n', 'd', NoDelay, "", "Turn on NODELAY TCP option");
|
||||
COMMAND('l', 'g', Linger, "", "Set LINGER socket option");
|
||||
COMMAND('g', 's', Getsockname, "", "Get socket name");
|
||||
COMMAND('g', 'p', Getsockname, "", "Get peer name");
|
||||
|
||||
AddSocketCommands();
|
||||
|
||||
RunTest(argc, argv);
|
||||
CleanupSockets();
|
||||
}
|
|
@ -1,198 +0,0 @@
|
|||
/*********************************************************************
|
||||
File : GUSI - Grand Unified Socket Interface
|
||||
File : GUSIPPCTest - Test PPC sockets
|
||||
Author : Matthias Neeracher <neeri@iis.ethz.ch>
|
||||
Language : MPW C
|
||||
|
||||
$Log$
|
||||
Revision 1.1.1.1 2001/03/03 21:49:39 chombier
|
||||
Initial import
|
||||
|
||||
Revision 1.1 2000/10/29 20:31:53 neeri
|
||||
Releasing 2.1.3
|
||||
|
||||
Revision 1.2 1994/12/31 01:05:05 neeri
|
||||
ANSIfy (omitting parameter names was illegal).
|
||||
|
||||
Revision 1.1 1994/02/25 02:47:36 neeri
|
||||
Initial revision
|
||||
|
||||
Revision 0.3 1993/06/20 00:00:00 neeri
|
||||
New sa_constr
|
||||
|
||||
Revision 0.2 1992/10/14 00:00:00 neeri
|
||||
Fix NBP type, usage messages
|
||||
|
||||
Revision 0.1 1992/09/08 00:00:00 neeri
|
||||
Factor out common socket routines
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#include "GUSITest.h"
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ppc.h>
|
||||
|
||||
#include <Events.h>
|
||||
#include <TextUtils.h>
|
||||
#include <PLStringFuncs.h>
|
||||
|
||||
void Socket(char ch1, char ch2, const char * line)
|
||||
{
|
||||
sock = socket(AF_PPC, SOCK_STREAM, 0);
|
||||
|
||||
if (sock == -1) {
|
||||
printf("# socket() returned error %s\n", Explain());
|
||||
Where();
|
||||
}
|
||||
}
|
||||
|
||||
void Bind(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
struct sockaddr_ppc addr;
|
||||
|
||||
if (sock == -1) {
|
||||
printf("# socket is not open\n");
|
||||
Where();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
addr.sppc_family = AF_PPC;
|
||||
addr.sppc_port.nameScript = smRoman;
|
||||
addr.sppc_port.portKindSelector = ppcByString;
|
||||
addr.sppc_location.locationKindSelector = ppcNBPTypeLocation;
|
||||
|
||||
if (sscanf(cmd, "%s %s", addr.sppc_port.name+1, addr.sppc_location.u.nbpType+1) != 2) {
|
||||
Usage(ch1, ch2);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
addr.sppc_port.name[0] = strlen(((char *)addr.sppc_port.name)+1);
|
||||
addr.sppc_location.u.nbpType[0] = strlen(((char *)&addr.sppc_location.u.nbpType)+1);
|
||||
|
||||
PLstrcpy((StringPtr) &addr.sppc_port.u.portTypeStr, "\pGUSIPPCTest");
|
||||
|
||||
if (bind(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_ppc))) {
|
||||
printf("bind() returned error %s\n", Explain());
|
||||
Where();
|
||||
}
|
||||
}
|
||||
|
||||
void Accept(char ch1, char ch2, const char * line)
|
||||
{
|
||||
socklen_t len;
|
||||
struct sockaddr_ppc addr;
|
||||
|
||||
if (sock == -1) {
|
||||
printf("# socket is not open\n");
|
||||
Where();
|
||||
|
||||
return;
|
||||
}
|
||||
if (accsock != -1) {
|
||||
printf("# can't accept more than one connection\n");
|
||||
Where();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
len = sizeof(struct sockaddr_ppc);
|
||||
sock = accept(accsock = sock, (struct sockaddr *) &addr, &len);
|
||||
|
||||
if (sock < 0) {
|
||||
printf("# accept() returned error %s\n", Explain());
|
||||
sock = accsock;
|
||||
accsock = -1;
|
||||
} else {
|
||||
addr.sppc_port.name[addr.sppc_port.name[0]+1] = 0;
|
||||
addr.sppc_port.u.portTypeStr[addr.sppc_port.u.portTypeStr[0]+1] = 0;
|
||||
printf(
|
||||
"# accepted connection from %s[%s]",
|
||||
((char *)addr.sppc_port.name)+1,
|
||||
((char *)addr.sppc_port.u.portTypeStr)+1);
|
||||
|
||||
switch (addr.sppc_location.locationKindSelector) {
|
||||
case ppcNBPLocation:
|
||||
addr.sppc_location.u.nbpEntity.objStr[addr.sppc_location.u.nbpEntity.objStr[0]+1] = 0;
|
||||
addr.sppc_location.u.nbpEntity.typeStr[addr.sppc_location.u.nbpEntity.typeStr[0]+1] = 0;
|
||||
addr.sppc_location.u.nbpEntity.zoneStr[addr.sppc_location.u.nbpEntity.zoneStr[0]+1] = 0;
|
||||
printf(
|
||||
"@%s:%s:%s\n",
|
||||
((char *)addr.sppc_location.u.nbpEntity.objStr)+1,
|
||||
((char *)addr.sppc_location.u.nbpEntity.typeStr)+1,
|
||||
((char *)addr.sppc_location.u.nbpEntity.zoneStr)+1);
|
||||
break;
|
||||
case ppcNBPTypeLocation:
|
||||
addr.sppc_location.u.nbpType[addr.sppc_location.u.nbpType[0]+1] = 0;
|
||||
printf("@%s\n", ((char *)addr.sppc_location.u.nbpType)+1);
|
||||
break;
|
||||
default:
|
||||
printf("\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Where();
|
||||
}
|
||||
|
||||
Boolean BrowseForName(struct sockaddr_ppc * name)
|
||||
{
|
||||
PortInfoRec info;
|
||||
|
||||
if (PPCBrowser(
|
||||
"\pConnect where?",
|
||||
(StringPtr) "\p",
|
||||
false,
|
||||
&name->sppc_location,
|
||||
&info,
|
||||
(PPCFilterUPP)nil,
|
||||
"\pGUSIPPCTest"))
|
||||
return false;
|
||||
|
||||
name->sppc_family = AF_PPC;
|
||||
name->sppc_port = info.name;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Connect(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
socklen_t len;
|
||||
struct sockaddr_ppc addr;
|
||||
|
||||
if (sock == -1) {
|
||||
printf("# socket is not open\n");
|
||||
Where();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!BrowseForName(&addr))
|
||||
return;
|
||||
|
||||
if (connect(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_ppc))) {
|
||||
printf("# connect() returned error %s\n", Explain());
|
||||
Where();
|
||||
}
|
||||
}
|
||||
|
||||
main(int argc, char ** argv)
|
||||
{
|
||||
printf("GUSIPPCTest MN 10Jan98\n\n");
|
||||
|
||||
COMMAND('s', 's', Socket, "", "Create a stream socket");
|
||||
COMMAND('b', 'd', Bind, "Name Type", "Bind to address");
|
||||
COMMAND('c', 'o', Connect, "", "Connect to address");
|
||||
COMMAND('a', 'c', Accept, "", "Accept a connection");
|
||||
|
||||
AddSocketCommands();
|
||||
|
||||
RunTest(argc, argv);
|
||||
CleanupSockets();
|
||||
}
|
|
@ -1,395 +0,0 @@
|
|||
/*********************************************************************
|
||||
File : GUSI - Grand Unified Socket Interface
|
||||
File : GUSISocketTest.c - Socket testing gear
|
||||
Author : Matthias Neeracher <neeri@iis.ethz.ch>
|
||||
Language : MPW C
|
||||
|
||||
$Log$
|
||||
Revision 1.1.1.1 2001/03/03 21:49:39 chombier
|
||||
Initial import
|
||||
|
||||
Revision 1.6 2000/05/23 06:41:40 neeri
|
||||
Separate out descriptor commands
|
||||
|
||||
Revision 1.5 1999/12/13 03:07:24 neeri
|
||||
Releasing 2.0.2
|
||||
|
||||
Revision 1.4 1999/11/15 07:52:30 neeri
|
||||
Last Call for 2.0.1
|
||||
|
||||
Revision 1.3 1999/08/02 06:59:24 neeri
|
||||
Added support for asynchronous errors
|
||||
|
||||
Revision 1.2 1999/04/10 04:25:54 neeri
|
||||
Change to more standard compliant headers
|
||||
|
||||
Revision 1.1 1998/10/25 11:57:27 neeri
|
||||
Ready to release 2.0a3
|
||||
|
||||
Revision 1.2 1994/12/31 01:12:21 neeri
|
||||
ANSIfy.
|
||||
Roundtrip benchmark.
|
||||
|
||||
Revision 1.1 1994/02/25 02:47:47 neeri
|
||||
Initial revision
|
||||
|
||||
Revision 0.1 1992/09/08 00:00:00 neeri
|
||||
Factor out more common code
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#include "GUSITest.h"
|
||||
#include <Types.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <LowMem.h>
|
||||
|
||||
int sock = -1;
|
||||
int accsock = -1;
|
||||
|
||||
void Close(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
if (close(sock)) {
|
||||
printf("# close() returned error %s\n", Explain());
|
||||
Where();
|
||||
}
|
||||
|
||||
sock = accsock;
|
||||
accsock = -1;
|
||||
}
|
||||
|
||||
void Listen(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
if (sock == -1) {
|
||||
printf("# socket is not open\n");
|
||||
Where();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (listen(sock, 5)) {
|
||||
printf("# listen() returned error %s\n", Explain());
|
||||
Where();
|
||||
}
|
||||
}
|
||||
|
||||
void Write(char ch1, char ch2, const char * line)
|
||||
{
|
||||
int len = strlen(line);
|
||||
int part;
|
||||
|
||||
if (sock == -1) {
|
||||
printf("# socket is not open\n");
|
||||
Where();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (; len; len -= part, line += part) {
|
||||
part = write(sock, line, len);
|
||||
if (part < 0) {
|
||||
printf("# write(\"%s\") returned error %s\n", line, Explain());
|
||||
Where();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Read(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
int len;
|
||||
char buf[500];
|
||||
char * line;
|
||||
|
||||
if (sock == -1) {
|
||||
printf("# socket is not open\n");
|
||||
Where();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
len = read(sock, buf, 500);
|
||||
|
||||
if (len < 0) {
|
||||
printf("# read() returned error %s\n", Explain());
|
||||
} else {
|
||||
buf[len] = 0;
|
||||
printf("# read() returned:\n");
|
||||
|
||||
for (line = strtok(buf, "\n\r"); line; line = strtok(nil, "\n\r"))
|
||||
printf("# %s\n", line);
|
||||
}
|
||||
|
||||
Where();
|
||||
}
|
||||
|
||||
void Select(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
int res;
|
||||
fd_set rdfds;
|
||||
fd_set wrfds;
|
||||
fd_set exfds;
|
||||
struct timeval delay;
|
||||
|
||||
if (sock == -1) {
|
||||
printf("# socket is not open\n");
|
||||
Where();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
FD_ZERO(&rdfds);
|
||||
FD_ZERO(&wrfds);
|
||||
FD_ZERO(&exfds);
|
||||
|
||||
FD_SET(sock, &rdfds);
|
||||
FD_SET(sock, &wrfds);
|
||||
FD_SET(sock, &exfds);
|
||||
|
||||
delay.tv_sec = 10;
|
||||
delay.tv_usec = 0;
|
||||
|
||||
res = select(sock+1, &rdfds, &wrfds, &exfds, &delay);
|
||||
|
||||
if (res < 0) {
|
||||
printf("# select() returned error %s\n", Explain());
|
||||
} else if (!res) {
|
||||
printf("# select() timed out\n");
|
||||
} else {
|
||||
printf(
|
||||
"# select() returned %s%s%s\n",
|
||||
FD_ISSET(sock, &rdfds) ? "canRead " : "",
|
||||
FD_ISSET(sock, &wrfds) ? "canWrite " : "",
|
||||
FD_ISSET(sock, &exfds) ? "exception " : "");
|
||||
}
|
||||
|
||||
Where();
|
||||
}
|
||||
|
||||
void TogBlk(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
int block;
|
||||
|
||||
if (sock == -1) {
|
||||
printf("# socket is not open\n");
|
||||
Where();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
switch (fcntl(sock, F_GETFL, 0)) {
|
||||
case 0:
|
||||
block = 1;
|
||||
break;
|
||||
default:
|
||||
block = 0;
|
||||
break;
|
||||
case -1:
|
||||
printf("# fcntl(F_GETFL) returned error %s\n", Explain());
|
||||
Where();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (fcntl(sock, F_SETFL, block ? O_NONBLOCK : 0))
|
||||
printf(
|
||||
"# ioctl(FIONBIO, %s) returned error %s\n",
|
||||
block ? "true" : "false",
|
||||
Explain());
|
||||
else
|
||||
printf("# Socket is now %s\n", block ? "nonblocking" : "blocking");
|
||||
|
||||
Where();
|
||||
}
|
||||
|
||||
void NRead(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
int nread;
|
||||
|
||||
if (sock == -1) {
|
||||
printf("# socket is not open\n");
|
||||
Where();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (ioctl(sock, FIONREAD, (long *) &nread))
|
||||
printf("# ioctl(FIONREAD) returned error %s\n", Explain());
|
||||
else
|
||||
printf("# %d bytes waiting to be read\n", nread);
|
||||
|
||||
Where();
|
||||
}
|
||||
|
||||
void GetError(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
int err;
|
||||
socklen_t len = sizeof(int);
|
||||
|
||||
if (sock == -1) {
|
||||
printf("# socket is not open\n");
|
||||
Where();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &err, &len))
|
||||
printf("# getsockopt(SOL_SOCKET, SO_ERROR) returned error %s\n", Explain());
|
||||
else {
|
||||
errno = err;
|
||||
printf("# Asynchronous error was %d (%s)\n", err, Explain());
|
||||
}
|
||||
|
||||
Where();
|
||||
}
|
||||
|
||||
static char BenchBuf[8192];
|
||||
|
||||
void BenchSer(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
char * at;
|
||||
int requestSize;
|
||||
int responseSize;
|
||||
int packetSize;
|
||||
int count;
|
||||
int i;
|
||||
|
||||
if (sock == -1) {
|
||||
printf("# socket is not open\n");
|
||||
Where();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
at = BenchBuf;
|
||||
|
||||
do {
|
||||
at += read(sock, at, 1024);
|
||||
*at = 0;
|
||||
} while (!strchr(BenchBuf, '\015'));
|
||||
|
||||
sscanf(BenchBuf, "%d %d %d\015", &requestSize, &responseSize, &count);
|
||||
|
||||
write(sock, BenchBuf, 1);
|
||||
|
||||
for (i=0; i++<count; ) {
|
||||
packetSize = 0;
|
||||
do {
|
||||
packetSize += read(sock, BenchBuf, 8192);
|
||||
} while (packetSize < requestSize);
|
||||
write(sock, BenchBuf, responseSize);
|
||||
}
|
||||
}
|
||||
|
||||
void BenchCli(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
int requestSize;
|
||||
int responseSize;
|
||||
int packetSize;
|
||||
int contribSize;
|
||||
int count;
|
||||
int i;
|
||||
long startTime;
|
||||
long transTime;
|
||||
Sampler readSamp;
|
||||
Sampler writeSamp;
|
||||
Sampler sizeSamp;
|
||||
|
||||
if (sock == -1) {
|
||||
printf("# socket is not open\n");
|
||||
Where();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (sscanf(cmd, "%d %d %d", &requestSize, &responseSize, &count) != 3) {
|
||||
Usage(ch1, ch2);
|
||||
return;
|
||||
}
|
||||
|
||||
InitSampler(&readSamp);
|
||||
InitSampler(&writeSamp);
|
||||
InitSampler(&sizeSamp);
|
||||
|
||||
write(sock, cmd, strlen(cmd)-1);
|
||||
write(sock, "\015", 1);
|
||||
read(sock, BenchBuf, 1);
|
||||
|
||||
startTime = LMGetTicks();
|
||||
|
||||
for (i=0; i++<count; ) {
|
||||
transTime = LMGetTicks();
|
||||
write(sock, BenchBuf, requestSize);
|
||||
Sample(&writeSamp, LMGetTicks()-transTime);
|
||||
packetSize = 0;
|
||||
transTime = LMGetTicks();
|
||||
do {
|
||||
contribSize = read(sock, BenchBuf, 8192);
|
||||
packetSize += contribSize;
|
||||
Sample(&sizeSamp, contribSize);
|
||||
} while (packetSize < responseSize);
|
||||
Sample(&readSamp, LMGetTicks()-transTime);
|
||||
}
|
||||
|
||||
printf("# Test took %d ticks.\n", LMGetTicks() - startTime);
|
||||
printf("# Read min: %2d max: %2d avg: %2.1f\n",
|
||||
readSamp.min, readSamp.max, ((double)readSamp.sum) / readSamp.count);
|
||||
printf("# Size min: %2d max: %2d avg: %2.1f\n",
|
||||
sizeSamp.min, sizeSamp.max, ((double)sizeSamp.sum) / sizeSamp.count);
|
||||
printf("# Write min: %2d max: %2d avg: %2.1f\n",
|
||||
writeSamp.min, writeSamp.max, ((double)writeSamp.sum) / writeSamp.count);
|
||||
}
|
||||
|
||||
void Shutdown(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
int what;
|
||||
|
||||
if (sock == -1) {
|
||||
printf("# socket is not open\n");
|
||||
Where();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (sscanf(cmd, "%d", &what) != 1) {
|
||||
Usage(ch1, ch2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (shutdown(sock, what))
|
||||
printf("# shutdown(%d) returned error %s\n", what, Explain());
|
||||
}
|
||||
|
||||
void AddDescriptorCommands()
|
||||
{
|
||||
COMMAND('c', 'l', Close, "", "Close socket");
|
||||
COMMAND('w', 'r', Write, "text", "Write a line");
|
||||
COMMAND('r', 'd', Read, "", "Read");
|
||||
COMMAND('s', 'e', Select, "", "Select a socket");
|
||||
COMMAND('t', 'b', TogBlk, "", "Toggle blocking status");
|
||||
COMMAND('n', 'r', NRead, "", "Number of bytes to be read");
|
||||
}
|
||||
|
||||
void AddSocketCommands()
|
||||
{
|
||||
AddDescriptorCommands();
|
||||
COMMAND('l', 'i', Listen, "", "Listen to socket");
|
||||
COMMAND('b', 's', BenchSer,"", "Benchmark, server side");
|
||||
COMMAND('b', 'c', BenchCli,"reqSz resSz ct","Benchmark, client side");
|
||||
COMMAND('g', 'e', GetError,"", "Get asynchronous error");
|
||||
COMMAND('s', 'd', Shutdown,"", "Shutdown one side of socket");
|
||||
}
|
||||
|
||||
void CleanupSockets()
|
||||
{
|
||||
if (sock != -1)
|
||||
close(sock);
|
||||
if (accsock != -1)
|
||||
close(accsock);
|
||||
}
|
Binary file not shown.
|
@ -1,310 +0,0 @@
|
|||
/*********************************************************************
|
||||
File : GUSI - Grand Unified Socket Interface
|
||||
File : GUSITest.c - Common testing gear
|
||||
Author : Matthias Neeracher <neeri@iis.ethz.ch>
|
||||
Language : MPW C
|
||||
|
||||
$Log$
|
||||
Revision 1.1.1.1 2001/03/03 21:49:54 chombier
|
||||
Initial import
|
||||
|
||||
Revision 1.4 2000/05/23 06:45:28 neeri
|
||||
Add profiler support
|
||||
|
||||
Revision 1.3 1999/06/28 05:43:30 neeri
|
||||
Handle signals
|
||||
|
||||
Revision 1.2 1999/04/10 04:26:22 neeri
|
||||
Get rid of nonstandard error codes
|
||||
|
||||
Revision 1.1 1998/10/25 11:57:28 neeri
|
||||
Ready to release 2.0a3
|
||||
|
||||
Revision 1.2 1994/12/31 01:15:09 neeri
|
||||
ANSIfy.
|
||||
Benchmark support.
|
||||
|
||||
Revision 1.1 1994/02/25 02:47:57 neeri
|
||||
Initial revision
|
||||
|
||||
Revision 0.2 1992/09/20 00:00:00 neeri
|
||||
Allow empty lines & comments
|
||||
|
||||
Revision 0.1 1992/09/08 00:00:00 neeri
|
||||
Factor out more common code
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#include <Memory.h>
|
||||
#include <QuickDraw.h>
|
||||
#include "GUSITest.h"
|
||||
#include <Types.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
#if __profile__
|
||||
#include <Profiler.h>
|
||||
#endif
|
||||
|
||||
#ifdef __MWERKS__
|
||||
#include <SIOUX.h>
|
||||
#endif
|
||||
|
||||
Boolean HellHoundOnMyTrail = true; /* Gotta keep on moving */
|
||||
char infilename[200];
|
||||
char * inputfrom;
|
||||
FILE * input;
|
||||
int inputline;
|
||||
CmdDef commands[NROFCMDS];
|
||||
|
||||
void Help(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
printf("Commands are:\n\n");
|
||||
|
||||
for (ch1 = 'a'; ch1 <= 'z'; ++ch1)
|
||||
for (ch2 = 0; ch2 <= 'z'; ch2 ? ++ch2 : (ch2 = 'a'))
|
||||
if (HELPMSG(ch1,ch2))
|
||||
printf(
|
||||
" %c%c %-25s -- %s\n",
|
||||
ch1,
|
||||
ch2 ? ch2 : ' ',
|
||||
USAGE(ch1,ch2),
|
||||
HELPMSG(ch1,ch2));
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void Where()
|
||||
{
|
||||
if (inputfrom)
|
||||
printf("File '%s'; Line %d\n", inputfrom, inputline);
|
||||
}
|
||||
|
||||
void Prompt()
|
||||
{
|
||||
if (!inputfrom)
|
||||
printf("[%d]%c", inputline, ' ');
|
||||
}
|
||||
|
||||
#define CASE(code) case code: return #code
|
||||
|
||||
const char * Explain()
|
||||
{
|
||||
switch (errno) {
|
||||
CASE(EPERM);
|
||||
CASE(ENOENT);
|
||||
CASE(ESRCH);
|
||||
CASE(EINTR);
|
||||
CASE(EIO);
|
||||
CASE(ENXIO);
|
||||
CASE(E2BIG);
|
||||
CASE(ENOEXEC);
|
||||
CASE(EBADF);
|
||||
CASE(ECHILD);
|
||||
CASE(ENOMEM);
|
||||
CASE(EACCES);
|
||||
CASE(EFAULT);
|
||||
CASE(EBUSY);
|
||||
CASE(EEXIST);
|
||||
CASE(EXDEV);
|
||||
CASE(ENODEV);
|
||||
CASE(ENOTDIR);
|
||||
CASE(EISDIR);
|
||||
CASE(EINVAL);
|
||||
CASE(ENFILE);
|
||||
CASE(EMFILE);
|
||||
CASE(ENOTTY);
|
||||
CASE(EFBIG);
|
||||
CASE(ENOSPC);
|
||||
CASE(ESPIPE);
|
||||
CASE(EROFS);
|
||||
CASE(EMLINK);
|
||||
CASE(EPIPE);
|
||||
CASE(EDOM);
|
||||
CASE(ERANGE);
|
||||
CASE(EWOULDBLOCK);
|
||||
CASE(EINPROGRESS);
|
||||
CASE(EALREADY);
|
||||
CASE(ENOTSOCK);
|
||||
CASE(EDESTADDRREQ);
|
||||
CASE(EMSGSIZE);
|
||||
CASE(EPROTOTYPE);
|
||||
CASE(ENOPROTOOPT);
|
||||
CASE(EPROTONOSUPPORT);
|
||||
CASE(ESOCKTNOSUPPORT);
|
||||
CASE(EOPNOTSUPP);
|
||||
CASE(EPFNOSUPPORT);
|
||||
CASE(EAFNOSUPPORT);
|
||||
CASE(EADDRINUSE);
|
||||
CASE(EADDRNOTAVAIL);
|
||||
CASE(ENETDOWN);
|
||||
CASE(ENETUNREACH);
|
||||
CASE(ENETRESET);
|
||||
CASE(ECONNABORTED);
|
||||
CASE(ECONNRESET);
|
||||
CASE(ENOBUFS);
|
||||
CASE(EISCONN);
|
||||
CASE(ENOTCONN);
|
||||
CASE(ESHUTDOWN);
|
||||
CASE(ETOOMANYREFS);
|
||||
CASE(ETIMEDOUT);
|
||||
CASE(ECONNREFUSED);
|
||||
CASE(ELOOP);
|
||||
CASE(ENAMETOOLONG);
|
||||
CASE(EHOSTDOWN);
|
||||
CASE(EHOSTUNREACH);
|
||||
CASE(ENOTEMPTY);
|
||||
CASE(ENOLCK);
|
||||
CASE(ENOSYS);
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
void Usage(char ch1, char ch2)
|
||||
{
|
||||
printf("# Usage is: %c%c %s\n", ch1, ch2 ? ch2 : ' ', USAGE(ch1,ch2));
|
||||
Where();
|
||||
}
|
||||
|
||||
void Dispatch(const char * command)
|
||||
{
|
||||
char ch1 = command[0];
|
||||
char ch2 = command[1];
|
||||
TestCmd exec;
|
||||
|
||||
/* We are guaranteed to have at least one valid character */
|
||||
|
||||
switch (ch1) {
|
||||
case '\n':
|
||||
case '#':
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ch2)
|
||||
++command;
|
||||
else {
|
||||
if (isspace(ch2)) {
|
||||
command += 1;
|
||||
ch2 = 0;
|
||||
} else
|
||||
command += 2;
|
||||
|
||||
/* Skip rest of first word */
|
||||
for (; *command && !isspace(*command); ++command);
|
||||
|
||||
/* Skip whitespace */
|
||||
while (isspace(*command))
|
||||
++command;
|
||||
}
|
||||
|
||||
if (isalpha(ch1) && (!ch2 || isalpha(ch2)) && (exec = DISPATCH(ch1,ch2)))
|
||||
exec(ch1, ch2, command);
|
||||
else {
|
||||
if (ch2)
|
||||
printf("# Unknown command: '%c%c'\n", ch1, ch2);
|
||||
else
|
||||
printf("# Unknown command: '%c'\n", ch1);
|
||||
|
||||
printf("# Type 'h' for a list of known commands.\n");
|
||||
|
||||
Where();
|
||||
}
|
||||
}
|
||||
|
||||
void Quit(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
HellHoundOnMyTrail = false;
|
||||
}
|
||||
|
||||
void signal_handler(int sig)
|
||||
{
|
||||
/* Don't do anything, just interrupt system calls */
|
||||
}
|
||||
|
||||
void Alarm(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
signal(SIGALRM, signal_handler);
|
||||
alarm(atoi(cmd));
|
||||
}
|
||||
|
||||
void InitSampler(Sampler * samp)
|
||||
{
|
||||
samp->count = 0;
|
||||
samp->min = 0x7FFFFFFF;
|
||||
samp->max = -samp->min;
|
||||
samp->sum = 0;
|
||||
}
|
||||
|
||||
void Sample(Sampler * samp, long sample)
|
||||
{
|
||||
++samp->count;
|
||||
if (sample < samp->min)
|
||||
samp->min = sample;
|
||||
if (sample > samp->max)
|
||||
samp->max = sample;
|
||||
samp->sum += sample;
|
||||
}
|
||||
|
||||
void RunTest(int argc, char ** argv)
|
||||
{
|
||||
struct sigaction act;
|
||||
char cmd[80];
|
||||
|
||||
#if __profile__
|
||||
ProfilerInit(collectDetailed, bestTimeBase, 100, 20);
|
||||
ProfilerSetStatus(0);
|
||||
#endif
|
||||
|
||||
COMMAND('h', 0, Help, "", "Print this list");
|
||||
COMMAND('a', 'l', Alarm, "n", "Raise an alarm in n seconds");
|
||||
COMMAND('q', 0, Quit, "", "End the sad existence of this program");
|
||||
|
||||
#ifdef __MWERKS__
|
||||
SIOUXSettings.asktosaveonclose = false;
|
||||
#else
|
||||
InitGraf((Ptr) &qd.thePort);
|
||||
#endif
|
||||
|
||||
act.sa_handler = signal_handler;
|
||||
act.sa_mask = 0;
|
||||
act.sa_flags = 0;
|
||||
sigaction(SIGINT, &act, NULL);
|
||||
|
||||
if (--argc <= 0)
|
||||
Help('h', 0, "");
|
||||
|
||||
do {
|
||||
if (argc > 0 && strcmp(inputfrom = *++argv, "-")) {
|
||||
printf("Executing %sÉ\n", inputfrom);
|
||||
input = fopen(inputfrom, "r");
|
||||
} else {
|
||||
inputfrom = 0;
|
||||
input = stdin;
|
||||
}
|
||||
|
||||
inputline = 1;
|
||||
|
||||
while (HellHoundOnMyTrail && (Prompt(), fgets(cmd, 80, input))) {
|
||||
#if __profile__
|
||||
ProfilerSetStatus(1);
|
||||
#endif
|
||||
Dispatch(cmd);
|
||||
#if __profile__
|
||||
ProfilerSetStatus(0);
|
||||
#endif
|
||||
++inputline;
|
||||
}
|
||||
} while (HellHoundOnMyTrail && --argc > 0);
|
||||
|
||||
#if __profile__
|
||||
ProfilerDump("\pGUSI.prof");
|
||||
ProfilerTerm();
|
||||
#endif
|
||||
|
||||
printf("So long, it's been good to know you.\n");
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
/*********************************************************************
|
||||
File : GUSI - Grand Unified Socket Interface
|
||||
File : GUSITest.h - Common testing gear
|
||||
Author : Matthias Neeracher <neeri@iis.ethz.ch>
|
||||
Language : MPW C
|
||||
|
||||
$Log$
|
||||
Revision 1.1.1.1 2001/03/03 21:49:54 chombier
|
||||
Initial import
|
||||
|
||||
Revision 1.2 2000/05/23 06:43:25 neeri
|
||||
Separate out descriptor commands
|
||||
|
||||
Revision 1.1 1998/10/25 11:57:29 neeri
|
||||
Ready to release 2.0a3
|
||||
|
||||
Revision 1.2 1994/12/31 01:18:29 neeri
|
||||
Benchmark support.
|
||||
|
||||
Revision 1.1 1994/02/25 02:48:06 neeri
|
||||
Initial revision
|
||||
|
||||
Revision 0.1 1992/09/08 00:00:00 neeri
|
||||
Factor out more common code
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef _GUSITEST_
|
||||
#define _GUSITEST_
|
||||
|
||||
typedef void (*TestCmd)(char ch1, char ch2, const char * restcmd);
|
||||
|
||||
#include "GUSITest_P.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
extern FILE * input;
|
||||
extern int inputline;
|
||||
|
||||
/* void COMMAND(
|
||||
char ch1, char ch2, Command name
|
||||
TestCmd p, Command to be run
|
||||
char * s, Arguments to command
|
||||
char * h); Explanation for command
|
||||
|
||||
Example:
|
||||
COMMAND('m', 'd', MkDir, "directory", "Make a new directory");
|
||||
*/
|
||||
|
||||
#define COMMAND(ch1,ch2,p,s,h) \
|
||||
DISPATCH(ch1,ch2) = (p), \
|
||||
USAGE(ch1,ch2) = (s), \
|
||||
HELPMSG(ch1,ch2) = (h)
|
||||
|
||||
/* An useful macro for dumping variables.
|
||||
|
||||
Example:
|
||||
DUMP(statbuf.st_dev,d);
|
||||
*/
|
||||
|
||||
#define DUMP(EXPR, MODE) printf("# %s = %"#MODE"\n", #EXPR, EXPR)
|
||||
|
||||
/* Add common commands for descriptors */
|
||||
|
||||
void AddDescriptorCommands();
|
||||
|
||||
/* Add common commands for sockets */
|
||||
|
||||
void AddSocketCommands();
|
||||
|
||||
/* Run the test. Define your commands with COMMAND and call this */
|
||||
|
||||
void RunTest(int argc, char ** argv);
|
||||
|
||||
/* Print a MPW executable location note */
|
||||
|
||||
void Where();
|
||||
|
||||
/* Print a prompt */
|
||||
|
||||
void Prompt();
|
||||
|
||||
/* Return a string of the current error number, e.g. "EINVAL" */
|
||||
|
||||
const char * Explain();
|
||||
|
||||
/* Print a usage message for a command */
|
||||
|
||||
void Usage(char ch1, char ch2);
|
||||
|
||||
/* Clean up sockets */
|
||||
|
||||
void CleanupSockets();
|
||||
|
||||
extern int sock; /* Socket to read/write to */
|
||||
extern int accsock; /* Socket to accept connections on */
|
||||
|
||||
/* Keep statistics on a series of values */
|
||||
|
||||
typedef struct {
|
||||
int count;
|
||||
long min;
|
||||
long max;
|
||||
long sum;
|
||||
} Sampler;
|
||||
|
||||
void InitSampler(Sampler * samp);
|
||||
void Sample(Sampler * samp, long sample);
|
||||
|
||||
#endif
|
|
@ -1,37 +0,0 @@
|
|||
/*********************************************************************
|
||||
Project : GUSI - Grand Unified Socket Interface
|
||||
File : GUSITest - Testing gear
|
||||
Author : Matthias Neeracher <neeri@iis.ethz.ch>
|
||||
Language : MPW C
|
||||
|
||||
$Log$
|
||||
Revision 1.1.1.1 2001/03/03 21:49:54 chombier
|
||||
Initial import
|
||||
|
||||
Revision 1.1 1998/10/25 11:57:30 neeri
|
||||
Ready to release 2.0a3
|
||||
|
||||
Revision 1.2 1994/12/31 01:16:51 neeri
|
||||
Add GU·I resource.
|
||||
|
||||
Revision 1.1 1994/02/25 02:48:17 neeri
|
||||
Initial revision
|
||||
|
||||
Revision 0.2 1993/03/03 00:00:00 neeri
|
||||
define GUSI_PREF_VERSION
|
||||
|
||||
Revision 0.1 1992/07/13 00:00:00 neeri
|
||||
Include GUSI.r
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#define GUSI_PREF_VERSION '0150'
|
||||
|
||||
#include "GUSI.r"
|
||||
|
||||
resource 'GU·I' (GUSIRsrcID) {
|
||||
text, mpw, noAutoSpin, useChdir, approxStat,
|
||||
noTCPDaemon, noUDPDaemon,
|
||||
noConsole,
|
||||
{};
|
||||
};
|
Binary file not shown.
|
@ -1,38 +0,0 @@
|
|||
/*********************************************************************
|
||||
File : GUSI - Grand Unified Socket Interface
|
||||
File : GUSITest_P.h - Common testing gear
|
||||
Author : Matthias Neeracher <neeri@iis.ethz.ch>
|
||||
Language : MPW C
|
||||
|
||||
$Log$
|
||||
Revision 1.1.1.1 2001/03/03 21:49:54 chombier
|
||||
Initial import
|
||||
|
||||
Revision 1.1 1994/02/25 02:48:27 neeri
|
||||
Initial revision
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef _GUSITEST_P_
|
||||
#define _GUSITEST_P_
|
||||
|
||||
#include <CType.h>
|
||||
|
||||
#define NROFCHARS 26
|
||||
#define DECODE(ch) ((ch) ? (ch) - (isupper(ch) ? 'A' : 'a') + 1 : 0)
|
||||
#define CMDCODE(ch1,ch2) (DECODE(ch1)*(NROFCHARS+1)+DECODE(ch2))
|
||||
#define NROFCMDS (NROFCHARS+1)*(NROFCHARS+1)
|
||||
|
||||
typedef struct {
|
||||
TestCmd proc;
|
||||
const char * syntax;
|
||||
const char * help;
|
||||
} CmdDef;
|
||||
|
||||
extern CmdDef commands[NROFCMDS];
|
||||
|
||||
#define DISPATCH(ch1,ch2) commands[CMDCODE(ch1,ch2)].proc
|
||||
#define USAGE(ch1,ch2) commands[CMDCODE(ch1,ch2)].syntax
|
||||
#define HELPMSG(ch1,ch2) commands[CMDCODE(ch1,ch2)].help
|
||||
|
||||
#endif
|
|
@ -1,147 +0,0 @@
|
|||
/*********************************************************************
|
||||
File : GUSI - Grand Unified Socket Interface
|
||||
File : GUSIThreadTest - Testthread related features
|
||||
Author : Matthias Neeracher <neeri@iis.ethz.ch>
|
||||
Language : MPW C
|
||||
|
||||
$Log$
|
||||
Revision 1.1.1.1 2001/03/03 21:49:54 chombier
|
||||
Initial import
|
||||
|
||||
Revision 1.1 2000/10/29 20:31:53 neeri
|
||||
Releasing 2.1.3
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#include "GUSITest.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <sched.h>
|
||||
|
||||
#include <LowMem.h>
|
||||
|
||||
typedef struct {
|
||||
pthread_mutex_t fMutex;
|
||||
int fCounter;
|
||||
int fLoops;
|
||||
char fType;
|
||||
} Shared;
|
||||
|
||||
void *
|
||||
MutexPerformanceProc(void *arg)
|
||||
{
|
||||
Shared * shared = (Shared *)arg;
|
||||
|
||||
int i;
|
||||
|
||||
if (shared->fType == 'm') {
|
||||
for (i = 0; i < shared->fLoops; i++) {
|
||||
pthread_mutex_lock(&shared->fMutex);
|
||||
shared->fCounter++;
|
||||
pthread_mutex_unlock(&shared->fMutex);
|
||||
}
|
||||
} else {
|
||||
pthread_mutex_lock(&shared->fMutex);
|
||||
pthread_mutex_unlock(&shared->fMutex);
|
||||
for (i = 0; i < shared->fLoops; i++) {
|
||||
shared->fCounter++;
|
||||
if (shared->fType == 'y')
|
||||
sched_yield();
|
||||
}
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
/* end incr */
|
||||
|
||||
void MutexPerformance(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
int nloops;
|
||||
int nthreads;
|
||||
pthread_t tid[20];
|
||||
Shared shared;
|
||||
int i;
|
||||
int fairness;
|
||||
unsigned long start_time;
|
||||
unsigned long stop_time;
|
||||
|
||||
if (sscanf(cmd, "%d %d", &shared.fLoops, &nthreads) != 2)
|
||||
Usage(ch1, ch2);
|
||||
else {
|
||||
if (nthreads < 1) {
|
||||
printf("Too few threads specified, using 1\n");
|
||||
nthreads = 1;
|
||||
} else if (nthreads > 20) {
|
||||
printf("Too many threads specified, using 20\n");
|
||||
nthreads = 20;
|
||||
}
|
||||
shared.fCounter = 0;
|
||||
shared.fType = ch1;
|
||||
pthread_mutex_init(&shared.fMutex, NULL);
|
||||
pthread_mutex_lock(&shared.fMutex);
|
||||
|
||||
for (i = 0; i < nthreads; i++)
|
||||
pthread_create(&tid[i], NULL, MutexPerformanceProc, &shared);
|
||||
|
||||
start_time = LMGetTicks();
|
||||
|
||||
pthread_mutex_unlock(&shared.fMutex);
|
||||
|
||||
/* 4wait for all the threads */
|
||||
pthread_join(tid[0], NULL);
|
||||
fairness = shared.fCounter;
|
||||
for (i = 1; i < nthreads; i++)
|
||||
pthread_join(tid[i], NULL);
|
||||
|
||||
stop_time = LMGetTicks();
|
||||
|
||||
printf("Time: %f seconds, Fairness: %.2f%\n",
|
||||
(stop_time - start_time) / 60.0,
|
||||
(fairness * 100.0) / ((shared.fLoops-1) * nthreads + 1));
|
||||
if (shared.fCounter != shared.fLoops * nthreads)
|
||||
printf("error: counter = %ld\n", shared.fCounter);
|
||||
|
||||
pthread_mutex_destroy(&shared.fMutex);
|
||||
}
|
||||
}
|
||||
|
||||
void Sleep(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
int seconds;
|
||||
|
||||
if (sscanf(cmd, "%d", &seconds) != 1)
|
||||
Usage(ch1, ch2);
|
||||
else
|
||||
printf("Remaining: %ds\n", sleep(seconds));
|
||||
}
|
||||
|
||||
void Times(char ch1, char ch2, const char * cmd)
|
||||
{
|
||||
time_t lmk, gmk;
|
||||
time_t now = time(NULL);
|
||||
struct tm * t = localtime(&now);
|
||||
printf("Localtime %d/%d/%d %d:%02d:%02d %s\n",
|
||||
t->tm_year+1900, t->tm_mon+1, t->tm_mday,
|
||||
t->tm_hour, t->tm_min, t->tm_sec, t->tm_isdst ? "DST" : "");
|
||||
lmk = mktime(t);
|
||||
|
||||
t = gmtime(&now);
|
||||
printf("GMtime %d/%d/%d %d:%02d:%02d %s\n",
|
||||
t->tm_year+1900, t->tm_mon+1, t->tm_mday,
|
||||
t->tm_hour, t->tm_min, t->tm_sec, t->tm_isdst ? "DST" : "");
|
||||
gmk = mktime(t);
|
||||
|
||||
printf("Now %u Local %u GM %u\n", now, lmk, gmk);
|
||||
}
|
||||
|
||||
main(int argc, char ** argv)
|
||||
{
|
||||
printf("GUSIFileTest MN 25OCt00\n\n");
|
||||
|
||||
COMMAND('m', 'p', MutexPerformance, "#loops #threads", "Test mutex performance");
|
||||
COMMAND('y', 'p', MutexPerformance, "#loops #threads", "Test yield performance");
|
||||
COMMAND('n', 'p', MutexPerformance, "#loops #threads", "Test noyield performance");
|
||||
COMMAND('s', 'l', Sleep, "seconds", "sleep");
|
||||
COMMAND('t', 'm', Times, "", "Test time related functions");
|
||||
|
||||
RunTest(argc, argv);
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
GUSI/MANIFEST
BIN
GUSI/MANIFEST
Binary file not shown.
BIN
GUSI/MacDistr
BIN
GUSI/MacDistr
Binary file not shown.
BIN
GUSI/Makefile.mk
BIN
GUSI/Makefile.mk
Binary file not shown.
436
GUSI/README
436
GUSI/README
|
@ -1,436 +0,0 @@
|
|||
GUSI 2 -- A multithreaded POSIX library
|
||||
INTRODUCTION
|
||||
|
||||
GUSI is an extension and partial replacement of the standard C runtime library
|
||||
supplied with your compiler. The main objective of GUSI is to faciliate the
|
||||
porting of software written for UNIX systems by implementing a substantial subset
|
||||
of the Single Unix Specification library routines:
|
||||
|
||||
- BSD style sockets.
|
||||
- Pthreads.
|
||||
- Many other POSIX facilities such as diropen().
|
||||
|
||||
REQUIREMENTS
|
||||
|
||||
To use GUSI, you need one of the following compilers:
|
||||
|
||||
- Metrowerks CodeWarrior Pro 5 or later.
|
||||
- SC/SCpp 8.8.4d1c1 or later.
|
||||
- MrC/MrCpp 4.1.0a6c1 or later.
|
||||
|
||||
GETTING STARTED
|
||||
|
||||
If you're new to GUSI, start by reading the manual in :doc:GUSI.pdf.
|
||||
|
||||
If you're using GUSI with the Metrowerks CodeWarrior IDE, also read
|
||||
:doc:GUSI_CW_Guide.pdf if you haver any difficulties getting your first GUSI
|
||||
project to compile/link.
|
||||
|
||||
If you're using GUSI in combination with the MPW shell and/or the MPW compilers,
|
||||
please run GUSI_Install.MPW. For more details, please consider reading the
|
||||
documentation in the doc folder.
|
||||
|
||||
To recompile GUSI with the MPW compilers, you need an STL library. I've found
|
||||
STLport, available at http://www.stlport.org/download.shtml, to work perfectly
|
||||
for my purposes. To install it, put it anywhere on your disk and run
|
||||
STLport_Install.MPW. Current versions of GUSI have been compiled with STLport 3.1.2.
|
||||
|
||||
GUSI USER LICENSE
|
||||
|
||||
My primary objective in distributing GUSI is to have it used as widely as
|
||||
possible, while protecting my moral rights of authorship and limiting my
|
||||
exposure to liability.
|
||||
|
||||
Copyright (C) 1992-2001 Matthias Neeracher
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose on any
|
||||
computer system, and to redistribute it freely, subject to the following
|
||||
restrictions:
|
||||
|
||||
- The author is not responsible for the consequences of use of this software,
|
||||
no matter how awful, even if they arise from defects in it.
|
||||
- The origin of this software must not be misrepresented, either by explicit
|
||||
claim or by omission.
|
||||
- You are allowed to distributed modified copies of the software, in source
|
||||
and binary form, provided they are marked plainly as altered versions, and
|
||||
are not misrepresented as being the original software.
|
||||
|
||||
While I am giving GUSI away for free, that does not mean that I don't like
|
||||
getting appreciation for it. If you want to do something for me beyond your
|
||||
obligations outlined above, you can
|
||||
|
||||
- Acknowledge the use of GUSI in the about box of your application and/or
|
||||
your documentation.
|
||||
- Send me a CD as described in
|
||||
http://www.iis.ee.ethz.ch/~neeri/macintosh/donations.html
|
||||
|
||||
BUGS, QUESTIONS, SUGGESTIONS
|
||||
|
||||
Please report any problems you experience with the code or the documentation to
|
||||
me. I'd also be interested in hearing about your success stories, if you have
|
||||
any.
|
||||
|
||||
GUSI ON WWW
|
||||
|
||||
An online version of the GUSI manual and a GUSI FAQ are available at
|
||||
http://www.iis.ee.ethz.ch/~neeri/macintosh.html
|
||||
|
||||
MAILING LIST
|
||||
|
||||
There is a mailing list for announcing new releases and discussions about
|
||||
how to make GUSI change your life. To subscribe, send a mail:
|
||||
|
||||
----------------------------------
|
||||
To: gusi-request@iis.ee.ethz.ch
|
||||
Subject: (is ignored)
|
||||
|
||||
subscribe
|
||||
----------------------------------
|
||||
|
||||
Mail is now processed by a daemon, so please follow the above format.
|
||||
|
||||
Matthias Neeracher
|
||||
20875 Valley Green Dr. #50
|
||||
Cupertino, CA 95014
|
||||
|
||||
e-Mail: <neeracher@mac.com>
|
||||
Fax: +1 (408) 514-2605 ext. 0023
|
||||
|
||||
KNOWN BUGS
|
||||
|
||||
- MSG_PEEK does not yet work for for native OpenTransport sockets, only for MacTCP
|
||||
sockets [John Cargill-Ek].
|
||||
- hstrerror() is not yet implemented [Darrell Walisser].
|
||||
|
||||
RELEASE NOTES
|
||||
|
||||
Version 2.1.9 22Jul01
|
||||
|
||||
- Fixed st_blksize for files on HFS+ volumes, made st_blksize be expressed in
|
||||
terms of st_blksize, not as 512 byte blocks [Marcel Riechert, Chris Nandor,
|
||||
MacPerl Bug #424874].
|
||||
- Errors in MPW calls would still not be propagated correctly in CW 68K code
|
||||
[Chris Nandor, MacPerl Bug #436537].
|
||||
- If STDOUT and STDERR were reidrected to the same file, MPW tools would not
|
||||
work correctly [Chris Nandor, MacPerl Bug #436506].
|
||||
|
||||
Version 2.1.8 02Jul01
|
||||
|
||||
- truncate() was broken [Chris Nandor, MacPerl Bug #436893].
|
||||
- errors of MPW calls wouldn't be propagated correctly in MWPPC code
|
||||
[Chris Nandor, MacPerl Bug #436537].
|
||||
- open(..., O_CREAT|O_EXCL) would fail with MPW sockets [Thomas Wegner, MacPerl Bug #425901].
|
||||
- S_ISFIFO and S_ISSOCK were broken (a bug apparently inherited straight from BSD).
|
||||
[Thomas Wegner, MacPerl Bug #430930].
|
||||
|
||||
Version 2.1.7 15Apr01
|
||||
|
||||
- Path resolution of absolute paths with embedded aliases was broken.
|
||||
- GUSIFSpGetCatInfo returned garbage in the ioNamePtr field [Alan Fry].
|
||||
|
||||
Version 2.1.6 08Apr01
|
||||
|
||||
- Fix handling of error codes in select() [Jean-Pierre Stierlin].
|
||||
- Paths starting with ::: were mishandled [Chris Nandor, MacPerl Bug #409940].
|
||||
- Made minor tweaks to make GUSI work better with Natty (Don't ask yet).
|
||||
- Fixed major bugs in relative path generation.
|
||||
- MPW tools were unable to open files which were open as windows
|
||||
[Thomas Wegner, MacPerl Bug #231006]
|
||||
- Used delete where delete[] was appropriate [Wade Williams].
|
||||
- Fixed handling of network configuration changes [Jean-Pierre Stierlin].
|
||||
- Fixed a number of logic bugs related to select() [Michael Johnson, Wade Williams].
|
||||
- Clean out fNextListener after accept() [Joe van Tunen].
|
||||
- Fixed CW Project to include specific directories rather than {Compiler}.
|
||||
|
||||
Version 2.1.5 21Jan01
|
||||
|
||||
- Make literate programming tools configurable to some extent [Jack Jansen].
|
||||
- Made countless tweaks to scheduling and wakeups [Andreas Grosam, Keith Stattenfield].
|
||||
- Prevent inlining of overridable functions [Andreas Grosam].
|
||||
- Socket options did not work properly for OT sockets created by accept [Andreas Grosam].
|
||||
- pthread_cond_timedwait never returned ETIMEDOUT [Andreas Grosam].
|
||||
|
||||
Version 2.1.4 22Dec00
|
||||
|
||||
- Using a GUSIFSxxx call before any POSIX calls could cause programs to hang
|
||||
because the default context was not initialized yet.
|
||||
- GUSIForeignThreads was unable to open ThreadsLib [Max Horn].
|
||||
- GUSI diagnostic messages were sometimes emitted at A5 unsafe times
|
||||
[Jean-Pierre Stierlin].
|
||||
- Added ssh entry in hard coded services table [Jean-Pierre Stierlin].
|
||||
|
||||
Version 2.1.3 29Oct00
|
||||
|
||||
- More CW 6 fixes, especially for massive problems with time related functions
|
||||
[Richard Wesley].
|
||||
- Nonstandard macros defined in sys/cdefs.h conflicted with CW macros [David Willis].
|
||||
- PPC sockets were totally broken; they seemed to have slipped entirely through any
|
||||
sort of acceptance testing [David Willis].
|
||||
- Deal with CW's non-standard signature for fdopen.
|
||||
- Include two new tests (GUSIThreadTest, GUSIPPCTest) in interactive test suite.
|
||||
- Switched to distributing XML versions of the CW projects for space savings and
|
||||
portability.
|
||||
|
||||
Version 2.1.2 16Oct00
|
||||
|
||||
- Fixes for CodeWarrior 6 [Jack Jansen, Jeff Shulman].
|
||||
- SC would always use A5 relative addresses, with disastrous consequences in
|
||||
completion routines [Jean-Pierre Stierlin].
|
||||
- The OpenTransport code for dealing with multiple incoming connections had
|
||||
severe bugs [Gordon McMillan].
|
||||
- Accommodate the fact that CodeWarrior internally uses a different numbering
|
||||
scheme for SIGINT [Jack Jansen].
|
||||
|
||||
Version 2.1.1 05Jun00
|
||||
|
||||
- Some functions were returning references to stack values [Alexandre Parenteau].
|
||||
- Fixed a shocking amount of bugs in time(), localtime(), and gmtime()
|
||||
[Jack Jansen, Alexandre Parenteau].
|
||||
- Keep DCon support from crashing under Sfio.
|
||||
- Introduced preliminary support for multiple descriptor tables.
|
||||
|
||||
Version 2.1.0 29May00
|
||||
|
||||
- Improved formatting of the woven documentation [Peter Teeson].
|
||||
- Updated to Universal Headers 3.3.1 [Tom Bayley].
|
||||
- Tuned scheduling again [Jack Jansen].
|
||||
- Implemented proper linger model, closing sockets immediately (while
|
||||
actually putting them into a background queue to allow pending data to
|
||||
be transmitted) [Rich Cook, Oebele Dijkstra].
|
||||
- MacTCP sockets would hang on close with pending data [Jack Jansen].
|
||||
- Fixed bugs in lseek for read-only files [Jack Jansen].
|
||||
- Failed OpenTransport DNS lookups would return garbage data instead of
|
||||
error [Karl Armstrong, Mike Johnson].
|
||||
- Repeatedly calling a connect on a nonblocking socket could cause an infinite
|
||||
loop [Mike Johnson].
|
||||
- Fixed leak in OT UDP sendto [Tom Bayley].
|
||||
- (Hopefully) fixed a problem that could cause select() not to return a
|
||||
ready to read status [Mike Johnson].
|
||||
|
||||
Version 2.0.6 14Mar00
|
||||
|
||||
- Fixed several race conditions causing hangs in OpenTransport code
|
||||
[Alexandre Parenteau].
|
||||
- Console would get initialized twice [Steven Gillispie].
|
||||
- Suffix finding code was broken [Alexandre Parenteau].
|
||||
- open(":x:y", O_RDWR) would create x as a file if it didn't exist [Alexandre Parenteau].
|
||||
- Temporary name creation would crash horribly [Alexandre Parenteau].
|
||||
- rename() was broken [Alexandre Parenteau].
|
||||
- Try to enforce alignment of struct and class fields when GUSI headers are
|
||||
included by clients with arbitrary default alignments [Alexandre Parenteau].
|
||||
- Custom thread switchers were not getting correctly reinstalled upon destruction
|
||||
of a thread [Andre Radke].
|
||||
- GUSIFileSpec::Resolve needed to clear fValidInfo [Alexandre Parenteau].
|
||||
- Accidentally had reversed the logic for my "fix" of the double destruction of detached
|
||||
threads [Stephen Coy].
|
||||
- getservbyname would crash if /etc/services did not exist
|
||||
[Christopher Stern, Alexandre Parenteau].
|
||||
|
||||
Version 2.0.5 06Mar00
|
||||
|
||||
- Added a visual manual for first time CodeWarrior GUSI users [Rich Cook].
|
||||
- Forgot include guard in inttypes.h
|
||||
- Device families did not check that the paths passed to them were device paths
|
||||
[Christopher Stern]
|
||||
- Sped up thread switching by a factor of up to 1000 [Jack Jansen].
|
||||
- Called InitGraf in one location without checking configuration flag
|
||||
[Alexandre Parenteau].
|
||||
- Used a flaky plausibility test for automatic InitGraf.
|
||||
- Detached threads were deleted twice [Stephen Coy].
|
||||
- Force order of static destructors by closing descriptors before deleting threads
|
||||
[Christopher Stern].
|
||||
- Checked for nonexistent devices in file calls [Alexandre Parenteau].
|
||||
- readdir() would always return an error at the end of the directory, which is against
|
||||
the specification [Alexandre Parenteau].
|
||||
- sleep() from the main thread didn't [Darrell Walisser].
|
||||
- Renamed CodeWarrior projects to .mcp for cross platform compilability [Chris Brown].
|
||||
|
||||
Version 2.0.4 16Jan00
|
||||
|
||||
- Updated to CodeWarrior 5.3 compilers (this shouldn't affect any existing CW 5 users
|
||||
negatively, I think. If it does, please alert me.).
|
||||
- Some of the macros in pthread.h had PTHREAD_ misspelled as PTHREADS_ [Mike Davis]
|
||||
- GUSI's version of rename() was incorrectly mangled, so clients would link with
|
||||
the standard rename() [Matthew Nolan].
|
||||
- Removing an open file in the temporary items folder would fail [Jack Jansen].
|
||||
|
||||
Version 2.0.3 13Dec99
|
||||
|
||||
- Closing a OpenTransport TCP socket with data pending would hang
|
||||
[Oebele Dijkstra, Darrell Walisser].
|
||||
- Calling gethostbyname() before any sockets were opened would malfunction.
|
||||
|
||||
Version 2.0.2 12Dec99
|
||||
|
||||
- Attempting to set SO_LINGER would crash [Keith Rollin].
|
||||
- Passing a null timezone argument to gettimeofday() would misbehave [Christopher Stern].
|
||||
- GUSISetThreadSwitcher would get the wrong linkage [Bruno Litman].
|
||||
- read() on OpenTransport TCP/IP sockets had wrong results on disconnected sockets
|
||||
[Keith Rollin].
|
||||
- select() would return a wrong result if any descriptors were ready for both reading
|
||||
and writing [Keith Rollin].
|
||||
- Added pause() call.
|
||||
|
||||
Version 2.0.1 14Nov99
|
||||
|
||||
- select() would sometimes unecessarily poll [David Lawrence].
|
||||
- Added GUSIwithPPCSockets, GUSIwithLocalSockets, which I had forgotten
|
||||
[Darrell Walisser].
|
||||
- GUSI would generate SIGINT for background applications if Command-. was
|
||||
pressed in the foreground application [Darrell Walisser].
|
||||
- Calling signal() before any sockets were created would crash [Darrell Walisser].
|
||||
- gethostname() would garble the name if running with TCP/IP off
|
||||
[Christopher Stern].
|
||||
- stat() would not return an error for nonexistent files [Christopher Stern].
|
||||
|
||||
Version 2.0 23Oct99
|
||||
|
||||
- Removed the advertising clause from the BSD headers, as UCB no longer
|
||||
requires it. Thanks!
|
||||
- Included DCon.h in the distribution so GUSI compiles even if you
|
||||
don't have DCon. Thanks to Ed Wynne, Phasic Interware, Inc.,
|
||||
for his permission to do so. [Steven Gillispie]
|
||||
|
||||
Version 2.0fc2 14Oct99
|
||||
|
||||
- Open Transport sockets didn't close their connections in an orderly way
|
||||
[Steven Gillispie].
|
||||
|
||||
Version 2.0fc1 25Sep99
|
||||
|
||||
- The number and severity of bug reports has decreased sufficiently to
|
||||
convince me to declare final candidate status on GUSI 2. Please report
|
||||
all bugs immediately.
|
||||
- Added sanity checks on A5 before attempting to call InitGraf [Brian Pink].
|
||||
- Renamed the socket option IPPROTO_IP/IP_BROADCAST to its correct name
|
||||
SOL_SOCKET/SO_BROADCAST [Chris Brown].
|
||||
|
||||
Version 2.0b10 08Sep99
|
||||
|
||||
- I found several bugs in GUSI when trying to port the Darwin Streaming Server
|
||||
to MacOS.
|
||||
- Attempted to deal with threads created outside GUSI (e.g. in PowerPlant)
|
||||
[Eli Bishop].
|
||||
- File manager sockets would misbehave when switching off read-ahead.
|
||||
- Implemented the interface detection ioctl calls for OpenTransport TCP/IP.
|
||||
- getsockname would not work on sockets returned fropm accept under
|
||||
OpenTransport.
|
||||
- recvfrom would not correctly return the sorce socket address under
|
||||
OpenTransport except for a connected datagram socket [Philippe Lang].
|
||||
- Nonblocking reads on OpenTransport stream sockets did in fact block.
|
||||
- Nonblocking reads on OpenTransport datagram sockets leaked memory.
|
||||
- Implemented inet_aton and minimal pthread_condattr and pthread_mutexattr
|
||||
support.
|
||||
- Fixed bugs in the documentation [Chris Brown]. Added warning about
|
||||
interaction between GUSIConfig and precompiled headers [Steven Gillispie].
|
||||
|
||||
Version 2.0b9 02Sep99
|
||||
|
||||
- OpenTransport operations in threads sometimes would hang
|
||||
[Brian Pink, David Catmull].
|
||||
|
||||
Version 2.0b8 25Aug99
|
||||
|
||||
- Fixed problems with nonblocking connects in MacTCP [Philippe Lang].
|
||||
- Open transport sockets needed to have an explicit unbind [Steven Gillispie].
|
||||
- Work on literate edition of the source code.
|
||||
|
||||
Version 2.0b7 04Aug99
|
||||
|
||||
- Adapted to CodeWarrior Pro 5.
|
||||
- Updated documentation.
|
||||
- Tried to clarify license and added pointer to donations page.
|
||||
|
||||
Version 2.0b6 01Aug99 (Happy 708th birthday, Switzerland!)
|
||||
|
||||
- Philippe Lang convinced me to support the SO_ERROR socket option, and while
|
||||
I was at it, I supported as many socket options as I reasonably could
|
||||
(mostly on Open Transport).
|
||||
- Found out that the member fields of a struct timespec are named tv_xxx, not
|
||||
ts_xxx, thanks to W. Richard Stevens' sample code.
|
||||
- Fixed conditional macros in sys/un.h [Michel Rabozee].
|
||||
- Calling MSL __close_all() turned out not to have been such a hot idea.
|
||||
|
||||
Version 2.0b5 19Jul99
|
||||
|
||||
- Rick Waits correctly pointed out that most of the new files
|
||||
promised in b4 were actually missing.
|
||||
- Fixed bug in MacTCP UDP code [Philippe Lang].
|
||||
- Specified bool support in Example project so it would compile again [Rick Waits].
|
||||
|
||||
Version 2.0b4 18Jul99
|
||||
|
||||
- Added support for SIOW based programs.
|
||||
- Added mkdir/rmdir.
|
||||
- Fixed Open Transport nonblocking connects [Philippe Lang].
|
||||
- Fixed long standing inability to give new files the right type and
|
||||
creator [Chris Jacobson].
|
||||
- Add MPW makefile and examples to :Examples [Rick Waits].
|
||||
|
||||
Version 2.0b3 30Jun99
|
||||
|
||||
- Added support for Standard C and UNIX 98 style signal handling.
|
||||
- Added support for using sfio with SC and MrC.
|
||||
- Improved performance of file I/O.
|
||||
- Tried to improve documentation for SC and MrC [Rick Waits].
|
||||
- Added GUSI_Install.MPW installation script.
|
||||
- Eradicated dependences on STL from GUSI headers.
|
||||
|
||||
Version 2.0b2 07Jun99
|
||||
|
||||
- Added support for SC[pp] and MrC[pp] compilers. I compiled with SCpp 8.8.4d1c1
|
||||
and MrCpp 4.1.0a5c3, and intend to maintain the code for newer, but not older
|
||||
versions of these compilers. Unfortunately, Stdio does not work yet when
|
||||
using GUSI with MrCpp due to shared library conflicts. I intend to support
|
||||
sfio for SC and MrC in the near future, though.
|
||||
- Added back STDIN_FILENO & co. Fixed various bad comments in header guards
|
||||
[Chris Jacobson].
|
||||
- select for OpenTransport datagram (UDP) sockets was broken [Philippe Lang].
|
||||
- Allow recursive locks for mutexes.
|
||||
- Added a CodeWarrior project files to simplify rebuilds.
|
||||
- Some more work on PPC sockets.
|
||||
|
||||
Version 2.0b1 14Apr99
|
||||
|
||||
- Added support for broadcast and multicast options [Tom Bayley, Quinn].
|
||||
- Rewrote GUSIConfig in C++.
|
||||
- Brought documentation up to date.
|
||||
- Event handling for AppleEvents was broken [Chris Jacobson].
|
||||
- Changed auto-spin default to off, as this feature has less importance in
|
||||
GUSI II and can easier be turned on with configuration files.
|
||||
- Introduced GUSIContextFactory to add more flexibility to GUSIContext
|
||||
creation. Made switching in and out fully virtualized.
|
||||
- Massively improved and simplified the handling of race conditions
|
||||
in wakeups [George Warner & Quinn]
|
||||
- Added support for the DCon debugging console, and also switched to DCon
|
||||
for our own debugging output.
|
||||
- Added support for the PPC (Program-to-program communications) toolbox.
|
||||
- Fixed several bugs in Open Transport support.
|
||||
- Removed GUSIwithThreading, which is no longer necessary.
|
||||
|
||||
Version 2.0a4 22Nov98
|
||||
|
||||
- Since my Mac is getting packed up, a hasty and somewhat incomplete, but
|
||||
interesting release.
|
||||
- Changed configuration system to explicit configuration files created with
|
||||
GUSI_Configurator. This change is not reflected in the examples yet.
|
||||
- Added OpenTransport TCP/IP support (finally!)
|
||||
|
||||
Version 2.0a3 25Oct98
|
||||
|
||||
- Added MacTCP UDP support, SIOUX support, MSG_PEEK support.
|
||||
- Fixed many bugs.
|
||||
- Started adapting old test programs in Examples
|
||||
|
||||
Version 2.0a2 11Oct98
|
||||
|
||||
- Much more feature complete version: Added most file routines and domain name
|
||||
support.
|
||||
- Incorporated as much as I could of Michel Rabozee's excellent feedback.
|
||||
|
||||
Version 2.0a1 02Aug98
|
||||
|
||||
- A sneak peek to give an impression of the flavor of the new facilities
|
||||
in GUSI2. This version is far from feature complete, lacking most file
|
||||
routines, UDP support, support for AppleTalk, OpenTransport support,
|
||||
and support of the domain name resolver.
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,177 +0,0 @@
|
|||
// <GUSIBasics.h>=
|
||||
#ifndef _GUSIBasics_
|
||||
#define _GUSIBasics_
|
||||
|
||||
#ifdef GUSI_SOURCE
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <ConditionalMacros.h>
|
||||
|
||||
// \section{Definition of compiler features}
|
||||
//
|
||||
// If possible, we use unnamed namespaces to wrap internal code.
|
||||
//
|
||||
// <Definition of compiler features>=
|
||||
#ifdef __MWERKS__
|
||||
#define GUSI_COMPILER_HAS_NAMESPACE
|
||||
#endif
|
||||
|
||||
#ifdef GUSI_COMPILER_HAS_NAMESPACE
|
||||
#define GUSI_USING_STD_NAMESPACE using namespace std; using namespace std::rel_ops;
|
||||
#else
|
||||
#define GUSI_USING_STD_NAMESPACE
|
||||
#endif
|
||||
|
||||
// Asynchronous MacOS calls need completion procedures which in classic 68K code
|
||||
// often take parameters in address registers. The way to handle this differs
|
||||
// a bit between compilers. Note that the [[pascal]] keyword is ignored when
|
||||
// generating CFM code.
|
||||
//
|
||||
// <Definition of compiler features>=
|
||||
#if TARGET_RT_MAC_CFM
|
||||
#define GUSI_COMPLETION_PROC_A0(proc, type) \
|
||||
void (*const proc##Entry)(type * param) = proc;
|
||||
#define GUSI_COMPLETION_PROC_A1(proc, type) \
|
||||
void (*const proc##Entry)(type * param) = proc;
|
||||
#elif defined(__MWERKS__)
|
||||
#define GUSI_COMPLETION_PROC_A0(proc, type) \
|
||||
static pascal void proc##Entry(type * param : __A0) { proc(param); }
|
||||
#define GUSI_COMPLETION_PROC_A1(proc, type) \
|
||||
static pascal void proc##Entry(type * param : __A1) { proc(param); }
|
||||
#else
|
||||
void * GUSIGetA0() ONEWORDINLINE(0x2008);
|
||||
void * GUSIGetA1() ONEWORDINLINE(0x2009);
|
||||
#define GUSI_COMPLETION_PROC_A0(proc, type) \
|
||||
static pascal void proc##Entry() \
|
||||
{ proc(reinterpret_cast<type *>(GUSIGetA0())); }
|
||||
#define GUSI_COMPLETION_PROC_A1(proc, type) \
|
||||
static pascal void proc##Entry() \
|
||||
{ proc(reinterpret_cast<type *>(GUSIGetA1())); }
|
||||
#endif
|
||||
// %define GUSI_COMPLETION_PROC_A0 GUSI_COMPLETION_PROC_A1
|
||||
//
|
||||
// SC seems to have an issue with mutable fields.
|
||||
//
|
||||
// <Definition of compiler features>=
|
||||
#if defined(__SC__)
|
||||
#define mutable
|
||||
#define GUSI_MUTABLE(class, field) const_cast<class *>(this)->field
|
||||
#else
|
||||
#define GUSI_MUTABLE(class, field) field
|
||||
#endif
|
||||
// SC pretends to support standard scoping rules, but is in fact broken in
|
||||
// some cases.
|
||||
//
|
||||
// <Definition of compiler features>=
|
||||
#if defined(__SC__)
|
||||
#define for if (0) ; else for
|
||||
#endif
|
||||
// The MPW compilers don't predeclare [[qd]].
|
||||
//
|
||||
// <Definition of compiler features>=
|
||||
#if defined(__SC__) || defined(__MRC__)
|
||||
#define GUSI_NEEDS_QD QDGlobals qd;
|
||||
#else
|
||||
#define GUSI_NEEDS_QD
|
||||
#endif
|
||||
// \section{Definition of hook handling}
|
||||
//
|
||||
// GUSI supports a number of hooks. Every one of them has a different prototype,
|
||||
// but is passed as a [[GUSIHook]]. Hooks are encoded with an [[OSType]].
|
||||
//
|
||||
// <Definition of hook handling>=
|
||||
typedef unsigned long OSType;
|
||||
typedef void (*GUSIHook)(void);
|
||||
void GUSISetHook(OSType code, GUSIHook hook);
|
||||
GUSIHook GUSIGetHook(OSType code);
|
||||
// Currently, three hooks are supported: [[GUSI_SpinHook]] defines a function to
|
||||
// be called when GUSI waits on an event.
|
||||
// [[GUSI_ExecHook]] defines a function that determines whether a file is to be
|
||||
// considered ``executable''. [[GUSI_EventHook]] defines a routine that is called
|
||||
// when a certain event happens. To install an event hook, pass [[GUSI_EventHook]]
|
||||
// plus the event code. A few events, that is mouse-down and high level events,
|
||||
// are handled automatically by GUSI. Passing [[-1]] for the hook disables default
|
||||
// handling of an event.
|
||||
//
|
||||
// <Definition of hook handling>=
|
||||
typedef bool (*GUSISpinFn)(bool wait);
|
||||
#define GUSI_SpinHook 'spin'
|
||||
|
||||
struct FSSpec;
|
||||
typedef bool (*GUSIExecFn)(const FSSpec * file);
|
||||
#define GUSI_ExecHook 'exec'
|
||||
|
||||
struct EventRecord;
|
||||
typedef void (*GUSIEventFn)(EventRecord * ev);
|
||||
#define GUSI_EventHook 'evnt'
|
||||
// For the purposes of the functions who actually call the hooks, here's the direct
|
||||
// interface.
|
||||
//
|
||||
// <Definition of hook handling>=
|
||||
#ifdef GUSI_INTERNAL
|
||||
extern GUSISpinFn gGUSISpinHook;
|
||||
extern GUSIExecFn gGUSIExecHook;
|
||||
#endif /* GUSI_INTERNAL */
|
||||
// \section{Definition of error handling}
|
||||
//
|
||||
// Like a good POSIX citizen, GUSI reports all errors in the [[errno]] global
|
||||
// variable. This happens either through the [[GUSISetPosixError]] routine, which
|
||||
// stores its argument untranslated, or through the [[GUSISetMacError]] routine,
|
||||
// which translates MacOS error codes into the correct POSIX codes. The mapping
|
||||
// of [[GUSISetMacError]] is not always appropriate, so some routines will have to
|
||||
// preprocess some error codes. [[GUSIMapMacError]] returns the POSIX error corresponding
|
||||
// to a MacOS error.
|
||||
//
|
||||
// The domain name routines use an analogous variable [[h_errno]], which is
|
||||
// manipulated with [[GUSISetHostError]] and [[GUSISetMacHostError]].
|
||||
//
|
||||
// All routines return 0 if 0 was passed and -1 otherwise.
|
||||
//
|
||||
// <Definition of error handling>=
|
||||
typedef short OSErr;
|
||||
|
||||
int GUSISetPosixError(int error);
|
||||
int GUSISetMacError(OSErr error);
|
||||
int GUSIMapMacError(OSErr error);
|
||||
int GUSISetHostError(int error);
|
||||
int GUSISetMacHostError(OSErr error);
|
||||
// POSIX routines should never set [[errno]] from nonzero to zero. On the other
|
||||
// hand, it's sometimes useful to see whether some particular region of the
|
||||
// program set the error code or not. Therefore, we have such regions allocate
|
||||
// a [[GUSIErrorSaver]] statically, which guarantees that previous error codes
|
||||
// get restored if necessary.
|
||||
//
|
||||
// <Definition of error handling>=
|
||||
class GUSIErrorSaver {
|
||||
public:
|
||||
GUSIErrorSaver() { fSavedErrno = ::errno; ::errno = 0; }
|
||||
~GUSIErrorSaver() { if (!::errno) ::errno = fSavedErrno; }
|
||||
private:
|
||||
int fSavedErrno;
|
||||
};
|
||||
// \section{Definition of event handling}
|
||||
//
|
||||
// [[GUSIHandleNextEvent]] events by calling handlers installed
|
||||
// using the [[GUSI_EventHook]] mechanism.
|
||||
//
|
||||
// <Definition of event handling>=
|
||||
void GUSIHandleNextEvent(long sleepTime);
|
||||
// \section{Definition of string formatting}
|
||||
//
|
||||
// We occasionally need sprintf. To keep compatibility with MSL, Stdio, and Sfio,
|
||||
// we use an internal version which can be overridden.
|
||||
//
|
||||
// <Definition of string formatting>=
|
||||
int GUSI_vsprintf(char * s, const char * format, va_list args);
|
||||
int GUSI_sprintf(char * s, const char * format, ...);
|
||||
|
||||
#endif /* GUSI_SOURCE */
|
||||
|
||||
#if TARGET_API_MAC_CARBON
|
||||
# define LMGetTicks() TickCount()
|
||||
#endif
|
||||
|
||||
#endif /* _GUSIBasics_ */
|
|
@ -1,409 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSIBuffer.nw - Buffering for GUSI
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:08 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.20 2001/01/17 08:33:14 neeri
|
||||
// % Need to set fOldBuffer to nil after deleting
|
||||
// %
|
||||
// % Revision 1.19 2000/10/16 04:34:22 neeri
|
||||
// % Releasing 2.1.2
|
||||
// %
|
||||
// % Revision 1.18 2000/05/23 06:53:14 neeri
|
||||
// % Improve formatting
|
||||
// %
|
||||
// % Revision 1.17 2000/03/15 07:22:06 neeri
|
||||
// % Enforce alignment choices
|
||||
// %
|
||||
// % Revision 1.16 1999/09/09 07:19:18 neeri
|
||||
// % Fix read-ahead switch-off
|
||||
// %
|
||||
// % Revision 1.15 1999/08/26 05:44:59 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.14 1999/06/30 07:42:05 neeri
|
||||
// % Getting ready to release 2.0b3
|
||||
// %
|
||||
// % Revision 1.13 1999/05/30 03:09:29 neeri
|
||||
// % Added support for MPW compilers
|
||||
// %
|
||||
// % Revision 1.12 1999/03/17 09:05:05 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// % Revision 1.11 1998/11/22 23:06:50 neeri
|
||||
// % Releasing 2.0a4 in a hurry
|
||||
// %
|
||||
// % Revision 1.10 1998/10/25 11:28:43 neeri
|
||||
// % Added MSG_PEEK support, recursive locks.
|
||||
// %
|
||||
// % Revision 1.9 1998/08/02 12:31:36 neeri
|
||||
// % Another typo
|
||||
// %
|
||||
// % Revision 1.8 1998/08/02 11:20:06 neeri
|
||||
// % Fixed some typos
|
||||
// %
|
||||
// % Revision 1.7 1998/01/25 20:53:51 neeri
|
||||
// % Engine implemented, except for signals & scheduling
|
||||
// %
|
||||
// % Revision 1.6 1997/11/13 21:12:08 neeri
|
||||
// % Fall 1997
|
||||
// %
|
||||
// % Revision 1.5 1996/12/22 19:57:55 neeri
|
||||
// % TCP streams work
|
||||
// %
|
||||
// % Revision 1.4 1996/12/16 02:16:02 neeri
|
||||
// % Add Size(), make inlines inline, use BlockMoveData
|
||||
// %
|
||||
// % Revision 1.3 1996/11/24 13:00:26 neeri
|
||||
// % Fix comment leaders
|
||||
// %
|
||||
// % Revision 1.2 1996/11/24 12:52:05 neeri
|
||||
// % Added GUSIPipeSockets
|
||||
// %
|
||||
// % Revision 1.1.1.1 1996/11/03 02:43:32 neeri
|
||||
// % Imported into CVS
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{Buffering for GUSI}
|
||||
//
|
||||
// This section defines four classes that handle buffering for GUSI:
|
||||
// [[GUSIScatterer]], [[GUSIGatherer]], and their common ancestor
|
||||
// [[GUSIScattGath]] convert between [[iovecs]] and simple buffers in the
|
||||
// absence of specialized communications routines. A [[GUSIRingBuffer]]
|
||||
// mediates between a producer and a consumer, one of which is typically
|
||||
// normal code and the other interrupt level code.
|
||||
//
|
||||
//
|
||||
// <GUSIBuffer.h>=
|
||||
#ifndef _GUSIBuffer_
|
||||
#define _GUSIBuffer_
|
||||
|
||||
#ifdef GUSI_SOURCE
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <MacTypes.h>
|
||||
|
||||
#include "GUSIDiag.h"
|
||||
#include "GUSIBasics.h"
|
||||
|
||||
#include <ConditionalMacros.h>
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=native
|
||||
#endif
|
||||
|
||||
// \section{Definition of scattering/gathering}
|
||||
//
|
||||
// A [[GUSIScattGath]] translates between an array of [[iovecs]] and a simple buffer,
|
||||
// allocating scratch space if necessary.
|
||||
//
|
||||
// <Definition of class [[GUSIScattGath]]>=
|
||||
class GUSIScattGath {
|
||||
protected:
|
||||
// On constructing a [[GUSIScattGath]], we pass an array of [[iovecs]]. For the
|
||||
// simpler functions, a variant with a single [[buffer]] and [[length]] is also
|
||||
// available.
|
||||
//
|
||||
// <Constructor and destructor for [[GUSIScattGath]]>=
|
||||
GUSIScattGath(const iovec *iov, int count, bool gather);
|
||||
GUSIScattGath(void * buffer, size_t length, bool gather);
|
||||
virtual ~GUSIScattGath();
|
||||
public:
|
||||
// The [[iovec]], the buffer and its length are then available for public scrutinity.
|
||||
// Copy constructor and assignment both are a bit nontrivial.
|
||||
//
|
||||
// <Public interface to [[GUSIScattGath]]>=
|
||||
const iovec * IOVec() const;
|
||||
int Count() const;
|
||||
void * Buffer() const;
|
||||
operator void *() const;
|
||||
int Length() const;
|
||||
int SetLength(int len) const;
|
||||
void operator=(const GUSIScattGath & other);
|
||||
GUSIScattGath(const GUSIScattGath & other);
|
||||
private:
|
||||
// \section{Implementation of scattering/gathering}
|
||||
//
|
||||
// A [[GUSIScattGath]] always consists of [[fIo]], an array of [[iovecs]], [[fCount]],
|
||||
// the number of sections in the array, and [[fLen]], the total size of the data area.
|
||||
// If [[fCount]] is 1, [[fBuf]] will be a copy of the pointer to the single section. If
|
||||
// [[fCount]] is greater than 1, [[fScratch]] will contain a [[Handle]] to a scratch
|
||||
// area of size [[len]] and [[fBuf]] will contain [[*scratch]]. If the object was
|
||||
// constructed without providing an [[iovec]] array, [[fTrivialIo]] will be set up
|
||||
// to hold one.
|
||||
//
|
||||
// <Privatissima of [[GUSIScattGath]]>=
|
||||
const iovec * fIo;
|
||||
iovec fTrivialIo;
|
||||
mutable int fCount;
|
||||
mutable Handle fScratch;
|
||||
mutable void * fBuf;
|
||||
mutable int fLen;
|
||||
bool fGather;
|
||||
};
|
||||
// A [[GUSIScatterer]] distributes the contents of a buffer over an array of
|
||||
// [[iovecs]].
|
||||
//
|
||||
// <Definition of class [[GUSIScatterer]]>=
|
||||
class GUSIScatterer : public GUSIScattGath {
|
||||
public:
|
||||
GUSIScatterer(const iovec *iov, int count)
|
||||
: GUSIScattGath(iov, count, false) {}
|
||||
GUSIScatterer(void * buffer, size_t length)
|
||||
: GUSIScattGath(buffer, length, false) {}
|
||||
|
||||
GUSIScatterer & operator=(const GUSIScatterer & other)
|
||||
{ *static_cast<GUSIScattGath *>(this) = other; return *this; }
|
||||
};
|
||||
// A [[GUSIGatherer]] collects the contents of an array of [[iovecs]] into a single
|
||||
// buffer.
|
||||
//
|
||||
// <Definition of class [[GUSIGatherer]]>=
|
||||
class GUSIGatherer : public GUSIScattGath {
|
||||
public:
|
||||
GUSIGatherer(const struct iovec *iov, int count)
|
||||
: GUSIScattGath(iov, count, true) {}
|
||||
GUSIGatherer(const void * buffer, size_t length)
|
||||
: GUSIScattGath(const_cast<void *>(buffer), length, true) {}
|
||||
|
||||
GUSIGatherer & operator=(const GUSIGatherer & other)
|
||||
{ *static_cast<GUSIScattGath *>(this) = other; return *this; }
|
||||
};
|
||||
|
||||
// \section{Definition of ring buffering}
|
||||
//
|
||||
// A [[GUSIRingBuffer]] typically has on one side a non-preeemptive piece of code
|
||||
// and on the other side a piece of interrupt code. To transfer data from and to
|
||||
// the buffer, two interfaces are available: A direct interface that transfers
|
||||
// memory, and an indirect interface that allocates memory regions and then
|
||||
// has OS routines transfer data from or to them
|
||||
//
|
||||
// <Definition of class [[GUSIRingBuffer]]>=
|
||||
class GUSIRingBuffer {
|
||||
public:
|
||||
// On construction of a [[GUSIRingBuffer]], a buffer of the specified size is
|
||||
// allocated and not released until destruction. [[operator void*]] may be used
|
||||
// to determine whether construction was successful.
|
||||
//
|
||||
// <Constructor and destructor for [[GUSIRingBuffer]]>=
|
||||
GUSIRingBuffer(size_t bufsiz);
|
||||
~GUSIRingBuffer();
|
||||
operator void*();
|
||||
// The direct interface to [[GUSIRingBuffer]] is straightforward: [[Produce]] copies
|
||||
// memory into the buffer, [[Consume]] copies memory from the buffer, [[Free]]
|
||||
// determines how much space there is for [[Produce]] and [[Valid]] determines
|
||||
// how much space there is for [[Consume]].
|
||||
//
|
||||
// <Direct interface for [[GUSIRingBuffer]]>=
|
||||
void Produce(void * from, size_t & len);
|
||||
void Produce(const GUSIGatherer & gather, size_t & len, size_t & offset);
|
||||
void Produce(const GUSIGatherer & gather, size_t & len);
|
||||
void Consume(void * to, size_t & len);
|
||||
void Consume(const GUSIScatterer & scatter, size_t & len, size_t & offset);
|
||||
void Consume(const GUSIScatterer & scatter, size_t & len);
|
||||
size_t Free();
|
||||
size_t Valid();
|
||||
// [[ProduceBuffer]] tries to find in the ring buffer a contiguous free block of
|
||||
// memory of the specified size [[len]] or otherwise the biggest available free
|
||||
// block, returns a pointer to it and sets [[len]] to its length. [[ValidBuffer]]
|
||||
// specifies that the next [[len]] bytes of the ring buffer now contain valid data.
|
||||
//
|
||||
// [[ConsumeBuffer]] returns a pointer to the next valid byte and sets [[len]] to
|
||||
// the minimum of the number of contiguous valid bytes and the value of len on
|
||||
// entry. [[FreeBuffer]] specifies that the next [[len]] bytes of the ring
|
||||
// buffer were consumed and are no longer needed.
|
||||
//
|
||||
// <Indirect interface for [[GUSIRingBuffer]]>=
|
||||
void * ProduceBuffer(size_t & len);
|
||||
void * ConsumeBuffer(size_t & len);
|
||||
void ValidBuffer(void * buffer, size_t len);
|
||||
void FreeBuffer(void * buffer, size_t len);
|
||||
// Before the nonpreemptive partner changes any of the buffer's data structures,
|
||||
// the [[GUSIRingBuffer]] member functions call [[Lock]], and after the change is
|
||||
// complete, they call [[Release]]. An interrupt level piece of code before
|
||||
// changing any data structures has to determine whether the buffer is locked by
|
||||
// calling [[Locked]]. If the buffer is locked or otherwise in an unsuitable state,
|
||||
// the code can specify a procedure to be called during the next [[Release]] by
|
||||
// calling [[Defer]]. A deferred procedure should call [[ClearDefer]] to avoid
|
||||
// getting activated again at the next opportunity.
|
||||
//
|
||||
// <Synchronization support for [[GUSIRingBuffer]]>=
|
||||
void Lock();
|
||||
void Release();
|
||||
bool Locked();
|
||||
typedef void (*Deferred)(void *);
|
||||
void Defer(Deferred def, void * ar);
|
||||
void ClearDefer();
|
||||
// It is possible to switch buffer sizes during the existence of a buffer, but we
|
||||
// have to be somewhat careful, since some asynchronous call may still be writing
|
||||
// into the old buffer. [[PurgeBuffers]], called at safe times, cleans up old
|
||||
// buffers.
|
||||
//
|
||||
// <Buffer switching for [[GUSIRingBuffer]]>=
|
||||
void SwitchBuffer(size_t bufsiz);
|
||||
size_t Size();
|
||||
void PurgeBuffers();
|
||||
// Sometimes, it's necessary to do nondestructive reads, a task complex enough to
|
||||
// warrant its own class.
|
||||
//
|
||||
// <Definition of class [[GUSIRingBuffer::Peeker]]>=
|
||||
class Peeker {
|
||||
public:
|
||||
Peeker(GUSIRingBuffer & buffer);
|
||||
~Peeker();
|
||||
|
||||
void Peek(void * to, size_t & len);
|
||||
void Peek(const GUSIScatterer & scatter, size_t & len);
|
||||
private:
|
||||
// A [[GUSIRingBuffer::Peeker]] has to keep its associated [[GUSIRingBuffer]] locked during
|
||||
// its entire existence.
|
||||
//
|
||||
// <Privatissima of [[GUSIRingBuffer::Peeker]]>=
|
||||
GUSIRingBuffer & fTopBuffer;
|
||||
GUSIRingBuffer * fCurBuffer;
|
||||
Ptr fPeek;
|
||||
// The core routine for reading is [[PeekBuffer]] which automatically advances the
|
||||
// peeker as well.
|
||||
//
|
||||
// <Privatissima of [[GUSIRingBuffer::Peeker]]>=
|
||||
void * PeekBuffer(size_t & len);
|
||||
};
|
||||
friend class Peeker;
|
||||
|
||||
void Peek(void * to, size_t & len);
|
||||
void Peek(const GUSIScatterer & scatter, size_t & len);
|
||||
private:
|
||||
// \section{Implementation of ring buffering}
|
||||
//
|
||||
// The buffer area of a ring buffer extends between [[fBuffer]] and [[fEnd]]. [[fValid]]
|
||||
// contains the number of valid bytes, while [[fFree]] and [[fSpare]] (Whose purpose
|
||||
// will be explained later) sum up to the number of free bytes. [[fProduce]] points at the
|
||||
// next free byte, while [[fConsume]] points at the next valid byte. [[fInUse]]
|
||||
// indicates that an asynchronous call might be writing into the buffer.
|
||||
//
|
||||
// <Privatissima of [[GUSIRingBuffer]]>=
|
||||
Ptr fBuffer;
|
||||
Ptr fEnd;
|
||||
Ptr fConsume;
|
||||
Ptr fProduce;
|
||||
size_t fFree;
|
||||
size_t fValid;
|
||||
size_t fSpare;
|
||||
bool fInUse;
|
||||
// The relationships between the various pointers are captured by [[Invariant]] which
|
||||
// uses the auxiliary function [[Distance]] to determine the distance between two
|
||||
// pointers in the presence of wrap around areas.
|
||||
//
|
||||
// <Privatissima of [[GUSIRingBuffer]]>=
|
||||
bool Invariant();
|
||||
size_t Distance(Ptr from, Ptr to);
|
||||
// The lock mechanism relies on [[fLocked]], and the deferred procedure and its argument
|
||||
// are stored in [[fDeferred]] and [[fDeferredArg]].
|
||||
//
|
||||
// <Privatissima of [[GUSIRingBuffer]]>=
|
||||
int fLocked;
|
||||
Deferred fDeferred;
|
||||
void * fDeferredArg;
|
||||
// We only switch the next time the buffer is empty, so we are prepared to create
|
||||
// the new buffer dynamically and forward requests to it for a while.
|
||||
//
|
||||
// <Privatissima of [[GUSIRingBuffer]]>=
|
||||
GUSIRingBuffer * fNewBuffer;
|
||||
GUSIRingBuffer * fOldBuffer;
|
||||
void ObsoleteBuffer();
|
||||
// The scatter/gather variants of [[Produce]] and [[Consume]] rely on a common
|
||||
// strategy.
|
||||
//
|
||||
// <Privatissima of [[GUSIRingBuffer]]>=
|
||||
void IterateIOVec(const GUSIScattGath & sg, size_t & len, size_t & offset, bool produce);
|
||||
};
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=reset
|
||||
#endif
|
||||
|
||||
// Clients need readonly access to the buffer address and read/write access to the length.
|
||||
// [[operator void*]] server to check whether the [[GUSIScattGath]] was constructed
|
||||
// successfully.
|
||||
//
|
||||
// <Inline member functions for class [[GUSIScattGath]]>=
|
||||
inline const iovec * GUSIScattGath::IOVec() const
|
||||
{ return fIo; }
|
||||
inline int GUSIScattGath::Count() const
|
||||
{ return fCount; }
|
||||
inline GUSIScattGath::operator void *() const
|
||||
{ return Buffer(); }
|
||||
inline int GUSIScattGath::Length() const
|
||||
{ return fLen; }
|
||||
inline int GUSIScattGath::SetLength(int len) const
|
||||
{ return GUSI_MUTABLE(GUSIScattGath, fLen) = len; }
|
||||
// <Inline member functions for class [[GUSIRingBuffer]]>=
|
||||
inline void GUSIRingBuffer::Produce(const GUSIGatherer & gather, size_t & len, size_t & offset)
|
||||
{
|
||||
IterateIOVec(gather, len, offset, true);
|
||||
}
|
||||
|
||||
inline void GUSIRingBuffer::Consume(const GUSIScatterer & scatter, size_t & len, size_t & offset)
|
||||
{
|
||||
IterateIOVec(scatter, len, offset, false);
|
||||
}
|
||||
|
||||
inline void GUSIRingBuffer::Produce(const GUSIGatherer & gather, size_t & len)
|
||||
{
|
||||
size_t offset = 0;
|
||||
|
||||
IterateIOVec(gather, len, offset, true);
|
||||
}
|
||||
|
||||
inline void GUSIRingBuffer::Consume(const GUSIScatterer & scatter, size_t & len)
|
||||
{
|
||||
size_t offset = 0;
|
||||
|
||||
IterateIOVec(scatter, len, offset, false);
|
||||
}
|
||||
// The lock support is rather straightforward.
|
||||
//
|
||||
// <Inline member functions for class [[GUSIRingBuffer]]>=
|
||||
inline void GUSIRingBuffer::Lock() { ++fLocked; }
|
||||
inline bool GUSIRingBuffer::Locked() { return (fLocked!=0); }
|
||||
inline void GUSIRingBuffer::ClearDefer() { fDeferred = nil; }
|
||||
inline void GUSIRingBuffer::Release()
|
||||
{
|
||||
GUSI_CASSERT_INTERNAL(fLocked > 0);
|
||||
if (--fLocked <= 0 && fDeferred)
|
||||
fDeferred(fDeferredArg);
|
||||
}
|
||||
inline void GUSIRingBuffer::Defer(Deferred def, void * ar)
|
||||
{
|
||||
fDeferred = def;
|
||||
fDeferredArg = ar;
|
||||
}
|
||||
// The size is stored only implicitely.
|
||||
//
|
||||
// <Inline member functions for class [[GUSIRingBuffer]]>=
|
||||
inline size_t GUSIRingBuffer::Size() { return fEnd - fBuffer; }
|
||||
// <Inline member functions for class [[GUSIRingBuffer]]>=
|
||||
inline void GUSIRingBuffer::Peek(void * to, size_t & len)
|
||||
{
|
||||
Peeker peeker(*this);
|
||||
|
||||
peeker.Peek(to, len);
|
||||
}
|
||||
|
||||
inline void GUSIRingBuffer::Peek(const GUSIScatterer & scatter, size_t & len)
|
||||
{
|
||||
Peeker peeker(*this);
|
||||
|
||||
peeker.Peek(scatter, len);
|
||||
}
|
||||
#endif /* GUSI_SOURCE */
|
||||
|
||||
#endif /* _GUSIBuffer_ */
|
|
@ -1,289 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSIConfig.nw - Configuration settings
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:10 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.18 2001/01/22 04:31:11 neeri
|
||||
// % Last minute changes for 2.1.5
|
||||
// %
|
||||
// % Revision 1.17 2001/01/17 08:40:17 neeri
|
||||
// % Prevent inlining of overridable functions
|
||||
// %
|
||||
// % Revision 1.16 2000/05/23 06:54:39 neeri
|
||||
// % Improve formatting, update to latest universal headers
|
||||
// %
|
||||
// % Revision 1.15 2000/03/15 07:10:29 neeri
|
||||
// % Fix suffix searching code
|
||||
// %
|
||||
// % Revision 1.14 2000/03/06 06:24:34 neeri
|
||||
// % Fix plausibility tests for A5
|
||||
// %
|
||||
// % Revision 1.13 1999/09/26 03:56:44 neeri
|
||||
// % Sanity check for A5
|
||||
// %
|
||||
// % Revision 1.12 1999/08/26 05:44:59 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.11 1999/06/28 05:57:03 neeri
|
||||
// % Support SIGINT generation
|
||||
// %
|
||||
// % Revision 1.10 1999/05/29 06:26:41 neeri
|
||||
// % Fixed header guards
|
||||
// %
|
||||
// % Revision 1.9 1999/03/29 09:51:28 neeri
|
||||
// % New configuration system with support for hardcoded configurations.
|
||||
// %
|
||||
// % Revision 1.8 1999/03/17 09:05:05 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// % Revision 1.7 1998/10/11 16:45:10 neeri
|
||||
// % Ready to release 2.0a2
|
||||
// %
|
||||
// % Revision 1.6 1998/08/01 21:32:01 neeri
|
||||
// % About ready for 2.0a1
|
||||
// %
|
||||
// % Revision 1.5 1998/01/25 20:53:52 neeri
|
||||
// % Engine implemented, except for signals & scheduling
|
||||
// %
|
||||
// % Revision 1.4 1997/11/13 21:12:10 neeri
|
||||
// % Fall 1997
|
||||
// %
|
||||
// % Revision 1.3 1996/11/24 13:00:27 neeri
|
||||
// % Fix comment leaders
|
||||
// %
|
||||
// % Revision 1.2 1996/11/24 12:52:06 neeri
|
||||
// % Added GUSIPipeSockets
|
||||
// %
|
||||
// % Revision 1.1.1.1 1996/11/03 02:43:32 neeri
|
||||
// % Imported into CVS
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{GUSI Configuration settings}
|
||||
//
|
||||
// GUSI stores its global configuration settings in the [[GUSIConfiguration]]
|
||||
// singleton class. To create the instance, GUSI calls the [[GUSISetupConfig]]
|
||||
// hook.
|
||||
//
|
||||
// <GUSIConfig.h>=
|
||||
#ifndef _GUSIConfig_
|
||||
#define _GUSIConfig_
|
||||
|
||||
#ifdef GUSI_SOURCE
|
||||
|
||||
#include "GUSIFileSpec.h"
|
||||
|
||||
#include <ConditionalMacros.h>
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=native
|
||||
#endif
|
||||
|
||||
// \section{Definition of configuration settings}
|
||||
//
|
||||
// The GUSIConfiguration has a single instance with read only access, accessible
|
||||
// with the static [[Instance]] member function.
|
||||
//
|
||||
// <Definition of class [[GUSIConfiguration]]>=
|
||||
class GUSIConfiguration {
|
||||
public:
|
||||
enum { kNoResource = -1, kDefaultResourceID = 10240 };
|
||||
|
||||
static GUSIConfiguration * Instance();
|
||||
static GUSIConfiguration * CreateInstance(short resourceID = kDefaultResourceID);
|
||||
|
||||
// To determine the file type and creator of a newly created file, we first try
|
||||
// to match one of the [[FileSuffix]] suffices.
|
||||
//
|
||||
// <Type and creator rules for newly created files>=
|
||||
struct FileSuffix {
|
||||
char suffix[4];
|
||||
OSType suffType;
|
||||
OSType suffCreator;
|
||||
};
|
||||
short fNumSuffices;
|
||||
FileSuffix * fSuffices;
|
||||
|
||||
void ConfigureSuffices(short numSuffices, FileSuffix * suffices);
|
||||
// If none of the suffices matches, we apply the default type and creator. These
|
||||
// rules are applied with [[SetDefaultFType]].
|
||||
//
|
||||
// <Type and creator rules for newly created files>=
|
||||
OSType fDefaultType;
|
||||
OSType fDefaultCreator;
|
||||
|
||||
void ConfigureDefaultTypeCreator(OSType defaultType, OSType defaultCreator);
|
||||
void SetDefaultFType(const GUSIFileSpec & name) const;
|
||||
// To simplify Macintosh friendly ports of simple, I/O bound programs it is
|
||||
// possible to specify automatic yielding on read() and write() calls.
|
||||
// [[AutoSpin]] will spin a cursor and/or yield the CPU if desired.
|
||||
//
|
||||
// <Automatic cursor spin>=
|
||||
bool fAutoSpin;
|
||||
|
||||
void ConfigureAutoSpin(bool autoSpin);
|
||||
void AutoSpin() const;
|
||||
// GUSI applications can crash hard if QuickDraw is not initialized. Therefore, we
|
||||
// offer to initialize it automatically with the [[fAutoInitGraf]] feature.
|
||||
//
|
||||
// <Automatic initialization of QuickDraw>=
|
||||
bool fAutoInitGraf;
|
||||
|
||||
void ConfigureAutoInitGraf(bool autoInitGraf);
|
||||
void AutoInitGraf();
|
||||
// Due to the organization of a UNIX filesystem, it is fairly easy to find
|
||||
// out how many subdirectories a given directory has, since the [[nlink]] field of
|
||||
// its inode will automatically contain the number of subdirectories[[+2]]. Therefore,
|
||||
// some UNIX derived code depends on this behaviour. When [[fAccurateStat]] is set,
|
||||
// GUSI emulates this behaviour, but be warned that this makes [[stat]] on
|
||||
// directories a much more expensive operation. If [[fAccurateStat]] is not set,
|
||||
// stat() gives the total number of entries in the directory[[+2]] as a conservative
|
||||
// estimate.
|
||||
//
|
||||
// <Various flags>=
|
||||
bool fAccurateStat;
|
||||
|
||||
void ConfigureAccurateStat(bool accurateState);
|
||||
// The [[fSigPipe]] feature causes a signal [[SIGPIPE]] to be raised if an attempt
|
||||
// is made to write to a broken pipe.
|
||||
//
|
||||
// <Various flags>=
|
||||
bool fSigPipe;
|
||||
|
||||
void ConfigureSigPipe(bool sigPipe);
|
||||
void BrokenPipe();
|
||||
// The [[fSigInt]] feature causes a signal [[SIGINT]] to be raised if the user presses
|
||||
// command-period.
|
||||
//
|
||||
// <Various flags>=
|
||||
bool fSigInt;
|
||||
|
||||
void ConfigureSigInt(bool sigInt);
|
||||
void CheckInterrupt();
|
||||
// If [[fSharedOpen]] is set, open() opens files with shared read/write permission.
|
||||
//
|
||||
// <Various flags>=
|
||||
bool fSharedOpen;
|
||||
|
||||
void ConfigureSharedOpen(bool sharedOpen);
|
||||
// If [[fHandleAppleEvents]] is set, GUSI automatically handles AppleEvents in its
|
||||
// event handling routine.
|
||||
//
|
||||
// <Various flags>=
|
||||
bool fHandleAppleEvents;
|
||||
|
||||
void ConfigureHandleAppleEvents(bool handleAppleEvents);
|
||||
protected:
|
||||
GUSIConfiguration(short resourceID = kDefaultResourceID);
|
||||
private:
|
||||
// \section{Implementation of configuration settings}
|
||||
//
|
||||
// The sole instance of [[GUSIConfiguration]] is created on demand.
|
||||
//
|
||||
// <Privatissima of [[GUSIConfiguration]]>=
|
||||
static GUSIConfiguration * sInstance;
|
||||
// [[ConfigureSuffices]] sets up the suffix table.
|
||||
//
|
||||
// <Privatissima of [[GUSIConfiguration]]>=
|
||||
bool fWeOwnSuffices;
|
||||
// [[AutoSpin]] tests the flag inline, but performs the actual spinning out of
|
||||
// line.
|
||||
//
|
||||
// <Privatissima of [[GUSIConfiguration]]>=
|
||||
void DoAutoSpin() const;
|
||||
// [[AutoInitGraf]] works rather similarly to [[AutoSpin]].
|
||||
//
|
||||
// <Privatissima of [[GUSIConfiguration]]>=
|
||||
void DoAutoInitGraf();
|
||||
// [[CheckInterrupt]] raises a [[SIGINT]] signal if desired.
|
||||
//
|
||||
// <Privatissima of [[GUSIConfiguration]]>=
|
||||
bool CmdPeriod(const EventRecord * event);
|
||||
};
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=reset
|
||||
#endif
|
||||
|
||||
// To create the sole instance of [[GUSIConfiguration]], we call [[GUSISetupConfig]]
|
||||
// which has to call [[GUSIConfiguration::CreateInstance]].
|
||||
//
|
||||
// <Definition of [[GUSISetupConfig]] hook>=
|
||||
#ifdef __MRC__
|
||||
#pragma noinline_func GUSISetupConfig
|
||||
#endif
|
||||
|
||||
extern "C" void GUSISetupConfig();
|
||||
// <Inline member functions for class [[GUSIConfiguration]]>=
|
||||
inline GUSIConfiguration * GUSIConfiguration::Instance()
|
||||
{
|
||||
if (!sInstance)
|
||||
GUSISetupConfig();
|
||||
if (!sInstance)
|
||||
sInstance = new GUSIConfiguration();
|
||||
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
inline GUSIConfiguration * GUSIConfiguration::CreateInstance(short resourceID)
|
||||
{
|
||||
if (!sInstance)
|
||||
sInstance = new GUSIConfiguration(resourceID);
|
||||
|
||||
return sInstance;
|
||||
}
|
||||
// <Inline member functions for class [[GUSIConfiguration]]>=
|
||||
inline void GUSIConfiguration::ConfigureDefaultTypeCreator(OSType defaultType, OSType defaultCreator)
|
||||
{
|
||||
fDefaultType = defaultType;
|
||||
fDefaultCreator = defaultCreator;
|
||||
}
|
||||
// <Inline member functions for class [[GUSIConfiguration]]>=
|
||||
inline void GUSIConfiguration::ConfigureAutoSpin(bool autoSpin)
|
||||
{
|
||||
fAutoSpin = autoSpin;
|
||||
}
|
||||
// <Inline member functions for class [[GUSIConfiguration]]>=
|
||||
inline void GUSIConfiguration::AutoSpin() const
|
||||
{
|
||||
if (fAutoSpin)
|
||||
DoAutoSpin();
|
||||
}
|
||||
// <Inline member functions for class [[GUSIConfiguration]]>=
|
||||
inline void GUSIConfiguration::ConfigureAutoInitGraf(bool autoInitGraf)
|
||||
{
|
||||
fAutoInitGraf = autoInitGraf;
|
||||
}
|
||||
// <Inline member functions for class [[GUSIConfiguration]]>=
|
||||
inline void GUSIConfiguration::AutoInitGraf()
|
||||
{
|
||||
if (fAutoInitGraf)
|
||||
DoAutoInitGraf();
|
||||
}
|
||||
// <Inline member functions for class [[GUSIConfiguration]]>=
|
||||
inline void GUSIConfiguration::ConfigureSigPipe(bool sigPipe)
|
||||
{
|
||||
fSigPipe = sigPipe;
|
||||
}
|
||||
// <Inline member functions for class [[GUSIConfiguration]]>=
|
||||
inline void GUSIConfiguration::ConfigureSigInt(bool sigInt)
|
||||
{
|
||||
fSigInt = sigInt;
|
||||
}
|
||||
// <Inline member functions for class [[GUSIConfiguration]]>=
|
||||
inline void GUSIConfiguration::ConfigureAccurateStat(bool accurateStat)
|
||||
{
|
||||
fAccurateStat = accurateStat;
|
||||
}
|
||||
inline void GUSIConfiguration::ConfigureSharedOpen(bool sharedOpen)
|
||||
{
|
||||
fSharedOpen = sharedOpen;
|
||||
}
|
||||
#endif /* GUSI_SOURCE */
|
||||
|
||||
#endif /* _GUSIConfig_ */
|
|
@ -1,506 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSIContext.nw - Thread and Process structures
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/07 09:50:40 chombier
|
||||
// % First Imported.
|
||||
// %
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:10 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.22 2001/01/22 04:31:11 neeri
|
||||
// % Last minute changes for 2.1.5
|
||||
// %
|
||||
// % Revision 1.21 2001/01/17 08:43:42 neeri
|
||||
// % Tweak scheduling
|
||||
// %
|
||||
// % Revision 1.20 2000/12/23 06:09:21 neeri
|
||||
// % May need to create context for IO completions
|
||||
// %
|
||||
// % Revision 1.19 2000/10/16 04:34:22 neeri
|
||||
// % Releasing 2.1.2
|
||||
// %
|
||||
// % Revision 1.18 2000/06/01 06:31:09 neeri
|
||||
// % Delete SigContext
|
||||
// %
|
||||
// % Revision 1.17 2000/05/23 06:56:19 neeri
|
||||
// % Improve formatting, add socket closing queue, tune scheduling
|
||||
// %
|
||||
// % Revision 1.16 2000/03/15 07:11:50 neeri
|
||||
// % Fix detached delete (again), switcher restore
|
||||
// %
|
||||
// % Revision 1.15 2000/03/06 08:10:09 neeri
|
||||
// % Fix sleep in main thread
|
||||
// %
|
||||
// % Revision 1.14 2000/03/06 06:13:46 neeri
|
||||
// % Speed up thread/process switching through minimal quotas
|
||||
// %
|
||||
// % Revision 1.13 1999/12/13 02:40:50 neeri
|
||||
// % GUSISetThreadSwitcher had Boolean <-> bool inconsistency
|
||||
// %
|
||||
// % Revision 1.12 1999/11/15 07:25:32 neeri
|
||||
// % Safe context setup. Check interrupts only in foreground.
|
||||
// %
|
||||
// % Revision 1.11 1999/09/09 07:18:06 neeri
|
||||
// % Added support for foreign threads
|
||||
// %
|
||||
// % Revision 1.10 1999/08/26 05:44:59 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.9 1999/06/28 05:59:02 neeri
|
||||
// % Add signal handling support
|
||||
// %
|
||||
// % Revision 1.8 1999/05/30 03:09:29 neeri
|
||||
// % Added support for MPW compilers
|
||||
// %
|
||||
// % Revision 1.7 1999/03/17 09:05:05 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// % Revision 1.6 1999/02/25 03:34:24 neeri
|
||||
// % Introduced GUSIContextFactory, simplified wakeup
|
||||
// %
|
||||
// % Revision 1.5 1998/11/22 23:06:51 neeri
|
||||
// % Releasing 2.0a4 in a hurry
|
||||
// %
|
||||
// % Revision 1.4 1998/10/11 16:45:11 neeri
|
||||
// % Ready to release 2.0a2
|
||||
// %
|
||||
// % Revision 1.3 1998/08/01 21:26:18 neeri
|
||||
// % Switch dynamically to threading model
|
||||
// %
|
||||
// % Revision 1.2 1998/02/11 12:57:11 neeri
|
||||
// % PowerPC Build
|
||||
// %
|
||||
// % Revision 1.1 1998/01/25 21:02:41 neeri
|
||||
// % Engine implemented, except for signals & scheduling
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{Thread and Process structures}
|
||||
//
|
||||
// This section defines the process and thread switching engine of GUSI.
|
||||
//
|
||||
// In some execution environments, completion routines execute at interrupt level.
|
||||
// GUSI therefore is designed so all information needed to operate from interrupt
|
||||
// level is accessible from a [[GUSISocket]]. This information is separated into
|
||||
// per-process data, collected in [[GUSIProcess]], and per-thread data, collected
|
||||
// in [[GUSIContext]]. [[GUSIProcess]] is always a singleton, while [[GUSIContext]]
|
||||
// is a singleton if threading is disabled, and has multiple instances if threading
|
||||
// is enabled. By delegating the [[GUSIContext]] creation process to an instance
|
||||
// of a [[GUSIContextFactory]], we gain some extra flexibility.
|
||||
//
|
||||
// As soon as GUSI has started an asynchronous call, it calls the [[Wait]] member
|
||||
// function of its context. [[msec]] will set a time limit after which the call will
|
||||
// return in any case. Exceptional events may also cause [[GUSIWait]] to return, so
|
||||
// it is not safe to assume that the call will have completed upon return.
|
||||
//
|
||||
//
|
||||
// <GUSIContext.h>=
|
||||
#ifndef _GUSIContext_
|
||||
#define _GUSIContext_
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/signal.h>
|
||||
|
||||
#include <MacTypes.h>
|
||||
#include <Threads.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
// To maintain correct state, we have to remain informed which thread is active, so
|
||||
// we install all sorts of hooks. Clients have to use the C++ interface or call
|
||||
// [[GUSINewThread]], [[GUSISetThreadSwitcher]], and [[GUSISetThreadTerminator]].
|
||||
// instead of the thread manager routines.
|
||||
//
|
||||
// <Definition of thread manager hooks>=
|
||||
OSErr GUSINewThread(
|
||||
ThreadStyle threadStyle, ThreadEntryProcPtr threadEntry, void *threadParam,
|
||||
Size stackSize, ThreadOptions options,
|
||||
void **threadResult, ThreadID *threadMade);
|
||||
OSErr GUSISetThreadSwitcher(ThreadID thread,
|
||||
ThreadSwitchProcPtr threadSwitcher, void *switchProcParam, Boolean inOrOut);
|
||||
OSErr GUSISetThreadTerminator(ThreadID thread,
|
||||
ThreadTerminationProcPtr threadTerminator, void *terminationProcParam);
|
||||
__END_DECLS
|
||||
|
||||
#ifndef GUSI_SOURCE
|
||||
|
||||
typedef struct GUSIContext GUSIContext;
|
||||
|
||||
#else
|
||||
|
||||
#include "GUSISpecific.h"
|
||||
#include "GUSIBasics.h"
|
||||
#include "GUSIContextQueue.h"
|
||||
|
||||
#include <Files.h>
|
||||
#include <Processes.h>
|
||||
#include <OSUtils.h>
|
||||
|
||||
// \section{Definition of completion handling}
|
||||
//
|
||||
// {\tt GUSIContext} is heavily circular both with classes declared herein and
|
||||
// in other files. Therefore, we start by declaring a few class names.
|
||||
//
|
||||
// <Name dropping for file GUSIContext>=
|
||||
class GUSISocket;
|
||||
class GUSIContext;
|
||||
class GUSIProcess;
|
||||
class GUSISigProcess;
|
||||
class GUSISigContext;
|
||||
class GUSITimer;
|
||||
|
||||
#include <ConditionalMacros.h>
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=native
|
||||
#endif
|
||||
|
||||
// Ultimately, we will call through to the thread manager, but if an application uses foreign
|
||||
// sources of threads, we might have to go through indirections.
|
||||
//
|
||||
// <Definition of class [[GUSIThreadManagerProxy]]>=
|
||||
class GUSIThreadManagerProxy {
|
||||
public:
|
||||
virtual OSErr NewThread(
|
||||
ThreadStyle threadStyle, ThreadEntryProcPtr threadEntry, void *threadParam,
|
||||
Size stackSize, ThreadOptions options, void **threadResult, ThreadID *threadMade);
|
||||
virtual OSErr SetThreadSwitcher(
|
||||
ThreadID thread, ThreadSwitchProcPtr threadSwitcher, void *switchProcParam,
|
||||
Boolean inOrOut);
|
||||
virtual OSErr SetThreadTerminator(
|
||||
ThreadID thread, ThreadTerminationProcPtr threadTerminator, void *terminatorParam);
|
||||
|
||||
virtual ~GUSIThreadManagerProxy() {}
|
||||
|
||||
static GUSIThreadManagerProxy * Instance();
|
||||
protected:
|
||||
GUSIThreadManagerProxy() {}
|
||||
|
||||
static GUSIThreadManagerProxy * MakeInstance();
|
||||
};
|
||||
// A [[GUSIProcess]] contains all the data needed to wake up a process:
|
||||
//
|
||||
// \begin{itemize}
|
||||
// \item The [[ProcessSerialNumber]] of the process.
|
||||
// \item The [[ThreadTaskRef]] if threads are enabled.
|
||||
// \item The contents of the A5 register.
|
||||
// \end{itemize}
|
||||
//
|
||||
// The sole instance of [[GUSIProcess]] is obtained by calling the [[GUSIProcess::Instance]] static member
|
||||
// function, which will create the instance if necessary. Interrupt level prcedures may access the application's
|
||||
// A5 register either manually by calling [[GetA5]] or simply by declaring a [[GUSIProcess::A5Saver]] in a scope.
|
||||
//
|
||||
// <Definition of class [[GUSIProcess]]>=
|
||||
enum GUSIYieldMode {
|
||||
kGUSIPoll, // Busy wait for some unblockable condition
|
||||
kGUSIBlock, // Wait for some blockable condition
|
||||
kGUSIYield // Yield to some other eligible thread
|
||||
};
|
||||
|
||||
class GUSIProcess {
|
||||
public:
|
||||
static GUSIProcess * Instance();
|
||||
static void DeleteInstance();
|
||||
void GetPSN(ProcessSerialNumber * psn);
|
||||
void AcquireTaskRef();
|
||||
ThreadTaskRef GetTaskRef();
|
||||
long GetA5();
|
||||
bool Threading();
|
||||
void Yield(GUSIYieldMode wait);
|
||||
void Wakeup();
|
||||
GUSISigProcess * SigProcess() { return fSigProcess; }
|
||||
void QueueForClose(GUSISocket * sock);
|
||||
// A [[GUSIProcess::A5Saver]] is a class designed to restore the process A5
|
||||
// register for the scope of its declaration.
|
||||
//
|
||||
// <Definition of class [[GUSIProcess::A5Saver]]>=
|
||||
class A5Saver {
|
||||
public:
|
||||
A5Saver(long processA5);
|
||||
A5Saver(GUSIContext * context);
|
||||
A5Saver(GUSIProcess * process);
|
||||
~A5Saver();
|
||||
private:
|
||||
long fSavedA5;
|
||||
};
|
||||
protected:
|
||||
friend class GUSIContext;
|
||||
|
||||
GUSIProcess(bool threading);
|
||||
~GUSIProcess();
|
||||
|
||||
int fReadyThreads;
|
||||
int fExistingThreads;
|
||||
GUSISigProcess * fSigProcess;
|
||||
private:
|
||||
// \section{Implementation of completion handling}
|
||||
//
|
||||
// [[Instance]] returns the sole instance of [[GUSIProcess]], creating it if
|
||||
// necessary.
|
||||
//
|
||||
// <Privatissima of [[GUSIProcess]]>=
|
||||
static GUSIProcess * sInstance;
|
||||
// Much of the information stored in a [[GUSIProcess]] is static and read-only.
|
||||
//
|
||||
// <Privatissima of [[GUSIProcess]]>=
|
||||
ProcessSerialNumber fProcess;
|
||||
ThreadTaskRef fTaskRef;
|
||||
long fA5;
|
||||
// The exception is the [[fClosing]] socket queue and some yielding related flags.
|
||||
//
|
||||
// <Privatissima of [[GUSIProcess]]>=
|
||||
GUSISocket * fClosing;
|
||||
UInt32 fResumeTicks;
|
||||
bool fWillSleep;
|
||||
bool fDontSleep;
|
||||
};
|
||||
// A [[GUSIContext]] gathers thread related data. The central operation on a
|
||||
// [[GUSIContext]] is [[Wakeup]]. If the process is not asleep when [[Wakeup]]
|
||||
// is called, it is marked for deferred wakeup.
|
||||
//
|
||||
// A [[GUSIContext]] can either be created from an existing thread manager
|
||||
// [[ThreadID]] or by specifying the parameters for a [[NewThread]] call.
|
||||
//
|
||||
// [[Current]] returns the current [[GUSIContext]]. [[Setup]] initializes the
|
||||
// default context for either the threading or the non-threading model.
|
||||
//
|
||||
// [[Yield]] suspends the current process or thread until something interesting
|
||||
// happens if [[wait]] is [[kGUSIBlock]. Otherwise, [[Yield]] switches,
|
||||
// but does not suspend. For an ordinary thread context, [[Yield]] simply yields
|
||||
// the thread. For the context in a non-threading application, [[Yield]] does a
|
||||
// [[WaitNextEvent]]. For the main thread context, [[Yield]] does both.
|
||||
//
|
||||
// [[Done]] tests whether the thread has terminated yet. If [[join]] is set,
|
||||
// the caller is willing to wait. [[Result]] returns the default location to store
|
||||
// the thread result if no other is specified.
|
||||
//
|
||||
// By default, a context is joinable. Calling [[Detach]] will cause the context to
|
||||
// be destroyed automatically upon thread termination, and joins are no longer allowed.
|
||||
// A joinable context will not be destroyed automatically before the end of the
|
||||
// program, so you will have to call [[Liquidate]] to do that.
|
||||
//
|
||||
// [[SetSwitchIn]], [[SetSwitchOut]], and [[SetTerminator]] set per-thread user
|
||||
// switch and termination procedures. [[SwitchIn]], [[SwitchOut]], and [[Terminate]]
|
||||
// call the user defined procedures then perform their own actions.
|
||||
//
|
||||
// <Definition of class [[GUSIContext]]>=
|
||||
class GUSIContext : public GUSISpecificTable {
|
||||
public:
|
||||
friend class GUSIProcess;
|
||||
friend class GUSIContextFactory;
|
||||
|
||||
ThreadID ID() { return fThreadID; }
|
||||
virtual void Wakeup();
|
||||
void ClearWakeups() { fWakeup = false; }
|
||||
GUSIProcess * Process() { return fProcess; }
|
||||
void Detach() { fFlags |= detached; }
|
||||
void Liquidate();
|
||||
OSErr Error() { return sError; }
|
||||
bool Done(bool join);
|
||||
void * Result() { return fResult; }
|
||||
GUSISigContext * SigContext() { return fSigContext; }
|
||||
|
||||
static GUSIContext * Current() { return sCurrentContext; }
|
||||
static GUSIContext * CreateCurrent(bool threading = false)
|
||||
{ if (!sCurrentContext) Setup(threading); return sCurrentContext; }
|
||||
static GUSIContext * Lookup(ThreadID id);
|
||||
static void Setup(bool threading);
|
||||
static bool Yield(GUSIYieldMode wait);
|
||||
static void SigWait(sigset_t sigs);
|
||||
static void SigSuspend();
|
||||
static bool Raise(bool allSigs = false);
|
||||
static sigset_t Pending();
|
||||
static sigset_t Blocked();
|
||||
|
||||
void SetSwitchIn(ThreadSwitchProcPtr switcher, void *switchParam);
|
||||
void SetSwitchOut(ThreadSwitchProcPtr switcher, void *switchParam);
|
||||
void SetTerminator(ThreadTerminationProcPtr terminator, void *terminationParam);
|
||||
|
||||
static GUSIContextQueue::iterator begin() { return sContexts.begin(); }
|
||||
static GUSIContextQueue::iterator end() { return sContexts.end(); }
|
||||
static void LiquidateAll() { sContexts.LiquidateAll(); }
|
||||
protected:
|
||||
// <Friends of [[GUSIContext]]>=
|
||||
friend class GUSIContextFactory;
|
||||
// The thread switcher updates the pointer to the current context and switches
|
||||
// the global error variables.
|
||||
//
|
||||
// <Friends of [[GUSIContext]]>=
|
||||
friend pascal void GUSIThreadSwitchIn(ThreadID thread, GUSIContext * context);
|
||||
friend pascal void GUSIThreadSwitchOut(ThreadID thread, GUSIContext * context);
|
||||
// The terminator wakes up the joining thread if a join is pending.
|
||||
//
|
||||
// <Friends of [[GUSIContext]]>=
|
||||
friend pascal void GUSIThreadTerminator(ThreadID thread, GUSIContext * context);
|
||||
|
||||
GUSIContext(ThreadID id);
|
||||
GUSIContext(
|
||||
ThreadEntryProcPtr threadEntry, void *threadParam,
|
||||
Size stackSize, ThreadOptions options, void **threadResult, ThreadID *threadMade);
|
||||
|
||||
virtual void SwitchIn();
|
||||
virtual void SwitchOut();
|
||||
virtual void Terminate();
|
||||
|
||||
// At this point, we need to introduce all the private data of a [[GUSIContext]].
|
||||
//
|
||||
// \begin{itemize}
|
||||
// \item [[fThreadID]] stores the thread manager thread ID.
|
||||
// \item [[fProcess]] keeps a pointer to the process structure, so completion
|
||||
// routines can get at it.
|
||||
// \item [[sCurrentContext]] always points at the current context.
|
||||
// \item [[sContexts]] contains a queue of all contexts.
|
||||
// \item [[sHasThreads]] reminds us whether we are threading or not.
|
||||
// \item We define our own switch-in and termination procedures. If the user specifies procedures
|
||||
// we store them in [[fSwitchInProc]], [[fSwitchOutProc]], and [[fTerminateProc]] and their parameters
|
||||
// in [[fSwitchInParam]], [[fSwitchOutParam]], and [[fTerminateParam]] so we can call through to them
|
||||
// from our procedures.
|
||||
// \item [[fJoin]] contains the context waiting for us to die;
|
||||
// \item [[done]] reminds us if the thread is still alive. [[detached]] guarantees
|
||||
// that we will never wait for that thread anymore.
|
||||
// \item Last of all, we keep the global error variables [[errno]] and [[h_errno]]
|
||||
// for each context in the [[fErrno]] and [[fHostErrno]] fields.
|
||||
// \end{itemize}
|
||||
//
|
||||
//
|
||||
// <Privatissima of [[GUSIContext]]>=
|
||||
ThreadID fThreadID;
|
||||
GUSIProcess * fProcess;
|
||||
GUSIContext * fNext;
|
||||
GUSISigContext * fSigContext;
|
||||
ThreadSwitchProcPtr fSwitchInProc;
|
||||
ThreadSwitchProcPtr fSwitchOutProc;
|
||||
ThreadTerminationProcPtr fTerminateProc;
|
||||
void * fSwitchInParam;
|
||||
void * fSwitchOutParam;
|
||||
void * fTerminateParam;
|
||||
void * fResult;
|
||||
GUSIContext * fJoin;
|
||||
enum {
|
||||
done = 1 << 0,
|
||||
detached= 1 << 1,
|
||||
asleep = 1 << 2
|
||||
};
|
||||
char fFlags;
|
||||
bool fWakeup;
|
||||
UInt32 fEntryTicks;
|
||||
int fErrno;
|
||||
int fHostErrno;
|
||||
|
||||
class Queue : public GUSIContextQueue {
|
||||
public:
|
||||
void LiquidateAll();
|
||||
|
||||
~Queue() { LiquidateAll(); }
|
||||
};
|
||||
|
||||
static Queue sContexts;
|
||||
static GUSIContext * sCurrentContext;
|
||||
static bool sCreatingCurrentContext;
|
||||
static bool sHasThreading;
|
||||
static OSErr sError;
|
||||
// The [[GUSIContext]] constructor links the context into the queue of existing
|
||||
// contexts and installs the appropriate thread hooks. We split this into two
|
||||
// routines: [[StartSetup]] does static setup before the thread id is determined,
|
||||
// [[FinishSetup]] does the queueing.
|
||||
//
|
||||
// <Privatissima of [[GUSIContext]]>=
|
||||
void StartSetup();
|
||||
void FinishSetup();
|
||||
// Destruction of a [[GUSIContext]] requires some cleanup.
|
||||
//
|
||||
// <Privatissima of [[GUSIContext]]>=
|
||||
virtual ~GUSIContext();
|
||||
};
|
||||
// [[GUSIContext]] instances are created by instances of [[GUSIContextFactory]].
|
||||
//
|
||||
// <Definition of class [[GUSIContextFactory]]>=
|
||||
class GUSIContextFactory {
|
||||
public:
|
||||
static GUSIContextFactory * Instance();
|
||||
static void SetInstance(GUSIContextFactory * instance);
|
||||
static void DeleteInstance();
|
||||
|
||||
virtual GUSIContext * CreateContext(ThreadID id);
|
||||
virtual GUSIContext * CreateContext(
|
||||
ThreadEntryProcPtr threadEntry, void *threadParam,
|
||||
Size stackSize, ThreadOptions options = kCreateIfNeeded,
|
||||
void **threadResult = nil, ThreadID *threadMade = nil);
|
||||
|
||||
virtual ~GUSIContextFactory();
|
||||
protected:
|
||||
GUSIContextFactory();
|
||||
};
|
||||
// To make it possible to install an alternative [[GUSIContextFactory]], we provide the
|
||||
// [[GUSISetupContextFactory()]] hook for overriding;
|
||||
//
|
||||
// <Definition of class [[GUSIContextFactory]]>=
|
||||
extern "C" void GUSISetupContextFactory();
|
||||
// Many asynchronous calls take the same style of I/O parameter block and thus
|
||||
// can be handled by the same completion procedure. [[StartIO]] prepares
|
||||
// a parameter block for asynchronous I/O; [[FinishIO]] waits for the I/O
|
||||
// to complete. The parameter block has to be wrapped in a [[GUSIIOPBWrapper]].
|
||||
//
|
||||
// <Definition of IO wrappers>=
|
||||
void GUSIStartIO(IOParam * pb);
|
||||
OSErr GUSIFinishIO(IOParam * pb);
|
||||
OSErr GUSIControl(IOParam * pb);
|
||||
template <class PB> struct GUSIIOPBWrapper {
|
||||
GUSIContext * fContext;
|
||||
PB fPB;
|
||||
|
||||
GUSIIOPBWrapper() {}
|
||||
GUSIIOPBWrapper(const PB & pb) { memcpy(&fPB, &pb, sizeof(PB)); }
|
||||
|
||||
PB * operator->(){ return &fPB; }
|
||||
void StartIO() { GUSIStartIO(reinterpret_cast<IOParam *>(&fPB)); }
|
||||
OSErr FinishIO() { return GUSIFinishIO(reinterpret_cast<IOParam *>(&fPB)); }
|
||||
OSErr Control() { return GUSIControl(reinterpret_cast<IOParam *>(&fPB)); }
|
||||
};
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=reset
|
||||
#endif
|
||||
|
||||
// <Inline member functions for file GUSIContext>=
|
||||
inline GUSIProcess * GUSIProcess::Instance()
|
||||
{
|
||||
if (!sInstance)
|
||||
sInstance = new GUSIProcess(GUSIContext::sHasThreading);
|
||||
return sInstance;
|
||||
}
|
||||
inline void GUSIProcess::DeleteInstance()
|
||||
{
|
||||
delete sInstance;
|
||||
sInstance = 0;
|
||||
}
|
||||
// <Inline member functions for file GUSIContext>=
|
||||
inline void GUSIProcess::GetPSN(ProcessSerialNumber * psn)
|
||||
{ *psn = fProcess; }
|
||||
inline void GUSIProcess::AcquireTaskRef()
|
||||
{ GetThreadCurrentTaskRef(&fTaskRef); }
|
||||
inline ThreadTaskRef GUSIProcess::GetTaskRef()
|
||||
{ return fTaskRef; }
|
||||
inline long GUSIProcess::GetA5()
|
||||
{ return fA5; }
|
||||
inline bool GUSIProcess::Threading()
|
||||
{ return fTaskRef!=0;}
|
||||
// An [[A5Saver]] is trivially implemented but it simplifies bookkeeping.
|
||||
//
|
||||
// <Inline member functions for file GUSIContext>=
|
||||
inline GUSIProcess::A5Saver::A5Saver(long processA5)
|
||||
{ fSavedA5 = SetA5(processA5); }
|
||||
inline GUSIProcess::A5Saver::A5Saver(GUSIProcess * process)
|
||||
{ fSavedA5 = SetA5(process->GetA5()); }
|
||||
inline GUSIProcess::A5Saver::A5Saver(GUSIContext * context)
|
||||
{ fSavedA5 = SetA5(context->Process()->GetA5()); }
|
||||
inline GUSIProcess::A5Saver::~A5Saver()
|
||||
{ SetA5(fSavedA5); }
|
||||
|
||||
#endif /* GUSI_SOURCE */
|
||||
|
||||
#endif /* _GUSIContext_ */
|
|
@ -1,237 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSIContext.nw - Thread and Process structures
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:10 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.9 2001/01/17 08:45:13 neeri
|
||||
// % Improve memory allocation safety somewhat
|
||||
// %
|
||||
// % Revision 1.8 2000/05/23 06:58:03 neeri
|
||||
// % Improve formatting
|
||||
// %
|
||||
// % Revision 1.7 2000/03/15 07:22:06 neeri
|
||||
// % Enforce alignment choices
|
||||
// %
|
||||
// % Revision 1.6 1999/08/26 05:45:00 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.5 1999/05/30 03:09:29 neeri
|
||||
// % Added support for MPW compilers
|
||||
// %
|
||||
// % Revision 1.4 1999/03/17 09:05:06 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// % Revision 1.3 1998/08/02 11:20:07 neeri
|
||||
// % Fixed some typos
|
||||
// %
|
||||
// % Revision 1.2 1998/08/01 21:32:02 neeri
|
||||
// % About ready for 2.0a1
|
||||
// %
|
||||
// % Revision 1.1 1998/01/25 21:02:43 neeri
|
||||
// % Engine implemented, except for signals & scheduling
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{Context Queues}
|
||||
//
|
||||
// At all times through its existence, a [[GUSIContext]] will exist in various
|
||||
// queues: A queue of all contexts, queues of contexts waiting on a socket
|
||||
// event, a mutex, or a condition variable, and so on. Since a context is often
|
||||
// in several queues simultaneously, it's better to define queues non-intrusively.
|
||||
//
|
||||
// <GUSIContextQueue.h>=
|
||||
#ifndef _GUSIContextQueue_
|
||||
#define _GUSIContextQueue_
|
||||
|
||||
#ifndef GUSI_SOURCE
|
||||
|
||||
typedef struct GUSIContextQueue GUSIContextQueue;
|
||||
#else
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
// \section{Definition of context queues}
|
||||
//
|
||||
// We'd like to avoid having to include \texttt{GUSIContext} here, for reasons that
|
||||
// should be rather obvious.
|
||||
//
|
||||
// <Name dropping for file GUSIContextQueue>=
|
||||
class GUSIContext;
|
||||
|
||||
#include <ConditionalMacros.h>
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=native
|
||||
#endif
|
||||
|
||||
// The class [[GUSIContextQueue]] tries to present an interface that is a subset of
|
||||
// what C++ standard library list template classes offer.
|
||||
//
|
||||
// <Definition of class [[GUSIContextQueue]]>=
|
||||
class GUSIContextQueue {
|
||||
public:
|
||||
GUSIContextQueue();
|
||||
~GUSIContextQueue();
|
||||
|
||||
bool empty();
|
||||
GUSIContext * front() const;
|
||||
GUSIContext * back() const;
|
||||
void push_front(GUSIContext * context);
|
||||
void push_back(GUSIContext * context);
|
||||
void push(GUSIContext * context) { push_back(context); }
|
||||
void pop_front();
|
||||
void pop() { pop_front(); }
|
||||
void remove(GUSIContext * context);
|
||||
|
||||
void Wakeup();
|
||||
|
||||
// We define a forward iterator, but no reverse iterator.
|
||||
//
|
||||
// <Define [[iterator]] for [[GUSIContextQueue]]>=
|
||||
struct element;
|
||||
class iterator {
|
||||
friend class GUSIContextQueue;
|
||||
public:
|
||||
iterator & operator++();
|
||||
iterator operator++(int);
|
||||
bool operator==(const iterator other) const;
|
||||
GUSIContext * operator*();
|
||||
GUSIContext * operator->();
|
||||
private:
|
||||
// A [[GUSIContextQueue::iterator]] is just a wrapper for a
|
||||
// [[GUSIContextQueue::element]].
|
||||
//
|
||||
// <Privatissima of [[GUSIContextQueue::iterator]]>=
|
||||
element * fCurrent;
|
||||
|
||||
iterator(element * elt) : fCurrent(elt) {}
|
||||
iterator() : fCurrent(0) {}
|
||||
};
|
||||
|
||||
iterator begin();
|
||||
iterator end();
|
||||
private:
|
||||
// \section{Implementation of context queues}
|
||||
//
|
||||
// Efficiency of context queues is quite important, so we provide a custom
|
||||
// allocator for queue elements.
|
||||
//
|
||||
// <Privatissima of [[GUSIContextQueue]]>=
|
||||
struct element {
|
||||
GUSIContext * fContext;
|
||||
element * fNext;
|
||||
|
||||
element(GUSIContext * context, element * next = 0)
|
||||
: fContext(context), fNext(next) {}
|
||||
void * operator new(size_t);
|
||||
void operator delete(void *, size_t);
|
||||
private:
|
||||
// Elements are allocated in blocks of increasing size.
|
||||
//
|
||||
// <Privatissima of [[GUSIContextQueue::element]]>=
|
||||
struct header {
|
||||
short fFree;
|
||||
short fMax;
|
||||
header *fNext;
|
||||
};
|
||||
static header * sBlocks;
|
||||
};
|
||||
// A [[GUSIContextQueue]] is a single linked list with a separate back pointer.
|
||||
//
|
||||
// <Privatissima of [[GUSIContextQueue]]>=
|
||||
element * fFirst;
|
||||
element * fLast;
|
||||
};
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=reset
|
||||
#endif
|
||||
|
||||
// <Inline member functions for class [[GUSIContextQueue]]>=
|
||||
inline GUSIContextQueue::GUSIContextQueue()
|
||||
: fFirst(0), fLast(0)
|
||||
{
|
||||
}
|
||||
// None of the member functions are very large, so we'll inline them.
|
||||
//
|
||||
// <Inline member functions for class [[GUSIContextQueue]]>=
|
||||
inline bool GUSIContextQueue::empty()
|
||||
{
|
||||
return !fFirst;
|
||||
}
|
||||
|
||||
inline GUSIContext * GUSIContextQueue::front() const
|
||||
{
|
||||
return fFirst ? fFirst->fContext : reinterpret_cast<GUSIContext *>(0);
|
||||
}
|
||||
|
||||
inline GUSIContext * GUSIContextQueue::back() const
|
||||
{
|
||||
return fLast ? fLast->fContext : reinterpret_cast<GUSIContext *>(0);
|
||||
}
|
||||
|
||||
inline void GUSIContextQueue::push_front(GUSIContext * context)
|
||||
{
|
||||
fFirst = new element(context, fFirst);
|
||||
if (!fLast)
|
||||
fLast = fFirst;
|
||||
}
|
||||
|
||||
inline void GUSIContextQueue::pop_front()
|
||||
{
|
||||
if (element * e = fFirst) {
|
||||
if (!(fFirst = fFirst->fNext))
|
||||
fLast = 0;
|
||||
delete e;
|
||||
}
|
||||
}
|
||||
// The constructors are not public, so only [[begin]] and [[end]] call them.
|
||||
//
|
||||
// <Inline member functions for class [[GUSIContextQueue]]>=
|
||||
inline GUSIContextQueue::iterator GUSIContextQueue::begin()
|
||||
{
|
||||
return iterator(fFirst);
|
||||
}
|
||||
|
||||
inline GUSIContextQueue::iterator GUSIContextQueue::end()
|
||||
{
|
||||
return iterator();
|
||||
}
|
||||
// <Inline member functions for class [[GUSIContextQueue]]>=
|
||||
inline GUSIContextQueue::iterator & GUSIContextQueue::iterator::operator++()
|
||||
{
|
||||
fCurrent = fCurrent->fNext;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline GUSIContextQueue::iterator GUSIContextQueue::iterator::operator++(int)
|
||||
{
|
||||
GUSIContextQueue::iterator it(*this);
|
||||
fCurrent = fCurrent->fNext;
|
||||
|
||||
return it;
|
||||
}
|
||||
|
||||
inline bool GUSIContextQueue::iterator::operator==(const iterator other) const
|
||||
{
|
||||
return fCurrent == other.fCurrent;
|
||||
}
|
||||
|
||||
inline GUSIContext * GUSIContextQueue::iterator::operator*()
|
||||
{
|
||||
return fCurrent->fContext;
|
||||
}
|
||||
|
||||
inline GUSIContext * GUSIContextQueue::iterator::operator->()
|
||||
{
|
||||
return fCurrent->fContext;
|
||||
}
|
||||
#endif /* GUSI_SOURCE */
|
||||
|
||||
#endif /* _GUSIContextQueue_ */
|
|
@ -1,69 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSIDCon.nw - DCon interface
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:10 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.4 2000/03/06 06:03:30 neeri
|
||||
// % Check device families for file paths
|
||||
// %
|
||||
// % Revision 1.3 1999/08/26 05:45:00 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.2 1999/05/29 06:26:41 neeri
|
||||
// % Fixed header guards
|
||||
// %
|
||||
// % Revision 1.1 1999/03/17 09:05:06 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{DCon interface}
|
||||
//
|
||||
// A [[GUSIDConSocket]] implements an interface to DCon, Cache Computing's
|
||||
// debugging console. For more information about DCon, see
|
||||
// \href{http://www.cache-computing.com/products/dcon/}{Cache Computing's site}
|
||||
// at \verb|http://www.cache-computing.com/products/dcon/|.
|
||||
//
|
||||
// All instances of [[GUSIDConSocket]] are created by the [[GUSIDConDevice]]
|
||||
// singleton, so
|
||||
// there is no point in exporting the class itself.
|
||||
//
|
||||
// <GUSIDCon.h>=
|
||||
#ifndef _GUSIDCon_
|
||||
#define _GUSIDCon_
|
||||
|
||||
#ifdef GUSI_INTERNAL
|
||||
|
||||
#include "GUSIDevice.h"
|
||||
|
||||
// \section{Definition of [[GUSIDConDevice]]}
|
||||
//
|
||||
// [[GUSIDConDevice]] is a singleton subclass of [[GUSIDevice]].
|
||||
//
|
||||
// <Definition of class [[GUSIDConDevice]]>=
|
||||
class GUSIDConDevice : public GUSIDevice {
|
||||
public:
|
||||
static GUSIDConDevice * Instance();
|
||||
virtual bool Want(GUSIFileToken & file);
|
||||
virtual GUSISocket * open(GUSIFileToken & file, int flags);
|
||||
protected:
|
||||
GUSIDConDevice() {}
|
||||
static GUSIDConDevice * sInstance;
|
||||
};
|
||||
|
||||
// <Inline member functions for class [[GUSIDConDevice]]>=
|
||||
inline GUSIDConDevice * GUSIDConDevice::Instance()
|
||||
{
|
||||
if (!sInstance)
|
||||
sInstance = new GUSIDConDevice;
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
#endif /* GUSI_INTERNAL */
|
||||
|
||||
#endif /* _GUSIDCon_ */
|
|
@ -1,217 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSIDescriptor.nw - Descriptor Table
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.2 2001/03/28 14:03:59 chombier
|
||||
// % GUSI 2.1.6b2 update
|
||||
// %
|
||||
// % Revision 1.1.1.1 2001/03/07 09:50:41 chombier
|
||||
// % First Imported.
|
||||
// %
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:10 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.15 2001/01/22 04:31:11 neeri
|
||||
// % Last minute changes for 2.1.5
|
||||
// %
|
||||
// % Revision 1.14 2001/01/17 08:40:17 neeri
|
||||
// % Prevent inlining of overridable functions
|
||||
// %
|
||||
// % Revision 1.13 2000/06/12 04:23:43 neeri
|
||||
// % Return values, not references; Introduce support for multiple descriptor tables
|
||||
// %
|
||||
// % Revision 1.12 2000/05/23 06:58:03 neeri
|
||||
// % Improve formatting
|
||||
// %
|
||||
// % Revision 1.11 2000/03/15 07:14:26 neeri
|
||||
// % Prevent double destruction of descriptor table
|
||||
// %
|
||||
// % Revision 1.10 2000/03/06 06:26:57 neeri
|
||||
// % Introduce (and call) CloseAllDescriptors()
|
||||
// %
|
||||
// % Revision 1.9 1999/08/26 05:45:01 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.8 1999/08/02 07:02:43 neeri
|
||||
// % Support for asynchronous errors and other socket options
|
||||
// %
|
||||
// % Revision 1.7 1999/06/30 07:42:05 neeri
|
||||
// % Getting ready to release 2.0b3
|
||||
// %
|
||||
// % Revision 1.6 1999/05/29 06:26:42 neeri
|
||||
// % Fixed header guards
|
||||
// %
|
||||
// % Revision 1.5 1999/04/29 05:00:48 neeri
|
||||
// % Fix bug with bizarre uses of dup2
|
||||
// %
|
||||
// % Revision 1.4 1999/03/17 09:05:06 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// % Revision 1.3 1998/10/11 16:45:12 neeri
|
||||
// % Ready to release 2.0a2
|
||||
// %
|
||||
// % Revision 1.2 1998/08/01 21:32:03 neeri
|
||||
// % About ready for 2.0a1
|
||||
// %
|
||||
// % Revision 1.1 1998/01/25 21:02:44 neeri
|
||||
// % Engine implemented, except for signals & scheduling
|
||||
// %
|
||||
// % Revision 1.1 1996/12/16 02:12:40 neeri
|
||||
// % TCP Sockets sort of work
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{Mapping descriptors to sockets}
|
||||
//
|
||||
// POSIX routines do not, of course, operate on [[GUSISockets]] but on
|
||||
// numerical descriptors. The [[GUSIDescriptorTable]] singleton maps between
|
||||
// descriptors and their [[GUSISockets]].
|
||||
//
|
||||
// <GUSIDescriptor.h>=
|
||||
#ifndef _GUSIDescriptor_
|
||||
#define _GUSIDescriptor_
|
||||
|
||||
#ifdef GUSI_SOURCE
|
||||
|
||||
#include "GUSISocket.h"
|
||||
|
||||
#include <ConditionalMacros.h>
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=native
|
||||
#endif
|
||||
|
||||
// \section{Definition of [[GUSIDescriptorTable]]}
|
||||
//
|
||||
// A [[GUSIDescriptorTable]] is another singleton class, behaving in many aspects
|
||||
// like an array of [[GUSISocket]] pointers. [[InstallSocket]] installs a new socket
|
||||
// into the table, picking the first available slot with a descriptor greater than
|
||||
// or equal to [[start]]. [[RemoveSocket]] empties one slot.
|
||||
// [[GUSIDescriptorTable::LookupSocket]] is a shorthand for
|
||||
// [[ (*GUSIDescriptorTable::Instance())[fd] ]].
|
||||
//
|
||||
// To allow for light-weight processes, we provide a copy constructor and
|
||||
// the [[SetInstance]] member.
|
||||
//
|
||||
// <Definition of class [[GUSIDescriptorTable]]>=
|
||||
class GUSIDescriptorTable {
|
||||
public:
|
||||
// enum { SIZE = 64 };
|
||||
enum { SIZE = 256 };
|
||||
|
||||
static GUSIDescriptorTable * Instance();
|
||||
|
||||
int InstallSocket(GUSISocket * sock, int start = 0);
|
||||
int RemoveSocket(int fd);
|
||||
GUSISocket * operator[](int fd);
|
||||
static GUSISocket * LookupSocket(int fd);
|
||||
|
||||
class iterator;
|
||||
friend class iterator;
|
||||
|
||||
iterator begin();
|
||||
iterator end();
|
||||
|
||||
~GUSIDescriptorTable();
|
||||
|
||||
static void CloseAllDescriptors();
|
||||
|
||||
static void SetInstance(GUSIDescriptorTable * table);
|
||||
|
||||
GUSIDescriptorTable();
|
||||
GUSIDescriptorTable(const GUSIDescriptorTable & parent);
|
||||
private:
|
||||
// \section{Implementation of [[GUSIDescriptorTable]]}
|
||||
//
|
||||
// On creation, a [[GUSIDescriptorTable]] clears all descriptors.
|
||||
//
|
||||
// <Privatissima of [[GUSIDescriptorTable]]>=
|
||||
GUSISocket * fSocket[SIZE];
|
||||
int fInvalidDescriptor;
|
||||
// <Privatissima of [[GUSIDescriptorTable]]>=
|
||||
static GUSIDescriptorTable * sGUSIDescriptorTable;
|
||||
};
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=reset
|
||||
#endif
|
||||
|
||||
// If no instance exists yet, [[GUSIDescriptorTable::Instance]] creates one and
|
||||
// calls [[GUSISetupConsole]] if the [[setupConsole]] parameter is true.
|
||||
// [[GUSISetupConsole]] calls [[GUSIDefaultSetupConsole]], which first calls
|
||||
// [[GUSISetupConsoleDescriptors]] to set up file descriptors 0, 1, and 2, and
|
||||
// then calls [[GUSISetupConsoleStdio]] to deal with the necessary initializations
|
||||
// on the stdio level.
|
||||
//
|
||||
// <Hooks for ANSI library interfaces>=
|
||||
extern "C" {
|
||||
void GUSISetupDescriptorTable();
|
||||
void GUSISetupConsole();
|
||||
void GUSIDefaultSetupConsole();
|
||||
void GUSISetupConsoleDescriptors();
|
||||
void GUSISetupConsoleStdio();
|
||||
}
|
||||
// Destructing a [[GUSIDescriptorTable]] may be a bit problematic, as this
|
||||
// may have effects reaching up into the stdio layer. We therefore factor
|
||||
// out the stdio aspects into the procedures [[StdioClose]] and [[StdioFlush]]
|
||||
// which we then can redefine in other, stdio library specific, libraries.
|
||||
//
|
||||
// <Hooks for ANSI library interfaces>=
|
||||
extern "C" {
|
||||
void GUSIStdioClose();
|
||||
void GUSIStdioFlush();
|
||||
}
|
||||
|
||||
// <Inline member functions for class [[GUSIDescriptorTable]]>=
|
||||
class GUSIDescriptorTable::iterator {
|
||||
public:
|
||||
iterator(GUSIDescriptorTable * table, int fd = 0) : fTable(table), fFd(fd) {}
|
||||
GUSIDescriptorTable::iterator & operator++();
|
||||
GUSIDescriptorTable::iterator operator++(int);
|
||||
int operator*() { return fFd; }
|
||||
bool operator==(const GUSIDescriptorTable::iterator & other) const;
|
||||
private:
|
||||
GUSIDescriptorTable * fTable;
|
||||
int fFd;
|
||||
};
|
||||
|
||||
inline GUSIDescriptorTable::iterator & GUSIDescriptorTable::iterator::operator++()
|
||||
{
|
||||
while (++fFd < fTable->fInvalidDescriptor && !fTable->fSocket[fFd])
|
||||
;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline GUSIDescriptorTable::iterator GUSIDescriptorTable::iterator::operator++(int)
|
||||
{
|
||||
int oldFD = fFd;
|
||||
|
||||
while (++fFd < fTable->fInvalidDescriptor && !fTable->fSocket[fFd])
|
||||
;
|
||||
|
||||
return GUSIDescriptorTable::iterator(fTable, oldFD);
|
||||
}
|
||||
|
||||
inline bool GUSIDescriptorTable::iterator::operator==(
|
||||
const GUSIDescriptorTable::iterator & other) const
|
||||
{
|
||||
return fFd == other.fFd;
|
||||
}
|
||||
|
||||
inline GUSIDescriptorTable::iterator GUSIDescriptorTable::begin()
|
||||
{
|
||||
return iterator(this);
|
||||
}
|
||||
|
||||
inline GUSIDescriptorTable::iterator GUSIDescriptorTable::end()
|
||||
{
|
||||
return iterator(this, fInvalidDescriptor);
|
||||
}
|
||||
|
||||
#endif /* GUSI_SOURCE */
|
||||
|
||||
#endif /* _GUSIDescriptor_ */
|
|
@ -1,381 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSIDevice.nw - Devices
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:10 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.13 2000/06/12 04:22:30 neeri
|
||||
// % Return values, not references
|
||||
// %
|
||||
// % Revision 1.12 2000/05/23 06:58:03 neeri
|
||||
// % Improve formatting
|
||||
// %
|
||||
// % Revision 1.11 2000/03/15 07:22:06 neeri
|
||||
// % Enforce alignment choices
|
||||
// %
|
||||
// % Revision 1.10 2000/03/06 06:30:30 neeri
|
||||
// % Check for nonexistent device
|
||||
// %
|
||||
// % Revision 1.9 1999/08/26 05:45:01 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.8 1999/07/19 06:21:02 neeri
|
||||
// % Add mkdir/rmdir, fix various file manager related bugs
|
||||
// %
|
||||
// % Revision 1.7 1999/05/29 06:26:42 neeri
|
||||
// % Fixed header guards
|
||||
// %
|
||||
// % Revision 1.6 1999/03/17 09:05:07 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// % Revision 1.5 1998/11/22 23:06:52 neeri
|
||||
// % Releasing 2.0a4 in a hurry
|
||||
// %
|
||||
// % Revision 1.4 1998/10/25 11:37:38 neeri
|
||||
// % More configuration hooks
|
||||
// %
|
||||
// % Revision 1.3 1998/10/11 16:45:13 neeri
|
||||
// % Ready to release 2.0a2
|
||||
// %
|
||||
// % Revision 1.2 1998/08/01 21:28:57 neeri
|
||||
// % Add directory operations
|
||||
// %
|
||||
// % Revision 1.1 1998/01/25 21:02:45 neeri
|
||||
// % Engine implemented, except for signals & scheduling
|
||||
// %
|
||||
// % Revision 1.1 1996/12/16 02:12:40 neeri
|
||||
// % TCP Sockets sort of work
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{Devices}
|
||||
//
|
||||
// Similar to the creation of sockets, operations on files like opening or
|
||||
// renaming them need to be dispatched to a variety of special cases (Most of
|
||||
// them of the form "Dev:" preceded by a device name). Analogous to the
|
||||
// [[GUSISocketFactory]] subclasses registered in a [[GUSISocketDomainRegistry]],
|
||||
// we therefore have subclasses of [[GUSIDevice]] registered in a
|
||||
// [[GUSIDeviceRegistry]], although the details of the two registries are
|
||||
// quite different.
|
||||
//
|
||||
// During resolution of a file name, the name and information about it is passed
|
||||
// around in a [[GUSIFileToken]].
|
||||
//
|
||||
// <GUSIDevice.h>=
|
||||
#ifndef _GUSIDevice_
|
||||
#define _GUSIDevice_
|
||||
|
||||
#ifdef GUSI_SOURCE
|
||||
|
||||
#include "GUSISocket.h"
|
||||
#include "GUSIFileSpec.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <utime.h>
|
||||
|
||||
#include <ConditionalMacros.h>
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=native
|
||||
#endif
|
||||
|
||||
// \section{Definition of [[GUSIFileToken]]}
|
||||
//
|
||||
// A [[GUSIFileToken]] consists of a pointer to the name as a C string, of a pointer
|
||||
// to the [[GUSIDevice]] the token resolves to, and, if the token refers to a
|
||||
// file name rather than a device name, a pointer to a [[GUSIFileSpec]]. Since
|
||||
// depending on the call, different [[GUSIDevice]] subclasses may handle it, a
|
||||
// request code has to be passed to the constructor, too.
|
||||
//
|
||||
// <Definition of class [[GUSIFileToken]]>=
|
||||
class GUSIDevice;
|
||||
|
||||
class GUSIFileToken : public GUSIFileSpec {
|
||||
public:
|
||||
enum Request {
|
||||
// \section{Operations on Devices}
|
||||
//
|
||||
// The [[open]] operation creates a new socket for the specified path or file
|
||||
// specification.
|
||||
//
|
||||
// <Requests for [[GUSIFileToken]]>=
|
||||
kWillOpen,
|
||||
// [[remove]] deletes a path or file specification.
|
||||
//
|
||||
// <Requests for [[GUSIFileToken]]>=
|
||||
kWillRemove,
|
||||
// [[rename]] renames a path or file specification.
|
||||
//
|
||||
// <Requests for [[GUSIFileToken]]>=
|
||||
kWillRename,
|
||||
// [[stat]] gathers statistical data about a file or directory.
|
||||
//
|
||||
// <Requests for [[GUSIFileToken]]>=
|
||||
kWillStat,
|
||||
// [[chmod]] changes file modes, to the extent that this is meaningful on MacOS.
|
||||
//
|
||||
// <Requests for [[GUSIFileToken]]>=
|
||||
kWillChmod,
|
||||
// [[utime]] bumps a file's modification time.
|
||||
//
|
||||
// <Requests for [[GUSIFileToken]]>=
|
||||
kWillUtime,
|
||||
// [[access]] checks access permissions for a file.
|
||||
//
|
||||
// <Requests for [[GUSIFileToken]]>=
|
||||
kWillAccess,
|
||||
// [[mkdir]] creates a directory.
|
||||
//
|
||||
// <Requests for [[GUSIFileToken]]>=
|
||||
kWillMkdir,
|
||||
// [[rmdir]] deletes a directory.
|
||||
//
|
||||
// <Requests for [[GUSIFileToken]]>=
|
||||
kWillRmdir,
|
||||
// [[opendir]] opens a directory handle on the given directory.
|
||||
//
|
||||
// <Requests for [[GUSIFileToken]]>=
|
||||
kWillOpendir,
|
||||
// [[symlink]] creates a symbolic link to a file.
|
||||
//
|
||||
// <Requests for [[GUSIFileToken]]>=
|
||||
kWillSymlink,
|
||||
// [[readlink]] reads the contents of a symbolic link.
|
||||
//
|
||||
// <Requests for [[GUSIFileToken]]>=
|
||||
kWillReadlink,
|
||||
// [[fgetfileinfo]] and [[fsetfileinfo]] reads and set the type and creator
|
||||
// code of a file.
|
||||
//
|
||||
// <Requests for [[GUSIFileToken]]>=
|
||||
kWillGetfileinfo,
|
||||
kWillSetfileinfo,
|
||||
// [[faccess]] manipulates MPW properties of files.
|
||||
//
|
||||
// <Requests for [[GUSIFileToken]]>=
|
||||
kWillFaccess,
|
||||
kNoRequest
|
||||
};
|
||||
|
||||
GUSIFileToken(const char * path, Request request, bool useAlias = false);
|
||||
GUSIFileToken(const GUSIFileSpec & spec, Request request);
|
||||
GUSIFileToken(short fRefNum, Request request);
|
||||
|
||||
bool IsFile() const { return fIsFile; }
|
||||
bool IsDevice() const { return !fIsFile; }
|
||||
Request WhichRequest() const { return fRequest; }
|
||||
GUSIDevice * Device() const { return fDevice; }
|
||||
const char * Path() const { return fPath; }
|
||||
|
||||
static bool StrFragEqual(const char * name, const char * frag);
|
||||
enum StdStream {
|
||||
kStdin,
|
||||
kStdout,
|
||||
kStderr,
|
||||
kConsole,
|
||||
kNoStdStream = -2
|
||||
};
|
||||
static StdStream StrStdStream(const char * name);
|
||||
|
||||
private:
|
||||
GUSIDevice * fDevice;
|
||||
const char * fPath;
|
||||
bool fIsFile;
|
||||
Request fRequest;
|
||||
};
|
||||
// \section{Definition of [[GUSIDirectory]]}
|
||||
//
|
||||
// [[GUSIDirectory]] is a directory handle to iterate over all entries in a
|
||||
// directory.
|
||||
//
|
||||
// <Definition of class [[GUSIDirectory]]>=
|
||||
class GUSIDirectory {
|
||||
public:
|
||||
virtual ~GUSIDirectory() {}
|
||||
virtual dirent * readdir() = 0;
|
||||
virtual long telldir() = 0;
|
||||
virtual void seekdir(long pos) = 0;
|
||||
virtual void rewinddir() = 0;
|
||||
protected:
|
||||
friend class GUSIDevice;
|
||||
GUSIDirectory() {}
|
||||
};
|
||||
// \section{Definition of [[GUSIDeviceRegistry]]}
|
||||
//
|
||||
// The [[GUSIDeviceRegistry]] is a singleton class registering all socket
|
||||
// domains.
|
||||
//
|
||||
// <Definition of class [[GUSIDeviceRegistry]]>=
|
||||
class GUSIDeviceRegistry {
|
||||
public:
|
||||
// The only instance of [[GUSIDeviceRegistry]] is, as usual, obtained by calling
|
||||
// [[Instance]].
|
||||
//
|
||||
// <Creation of [[GUSIDeviceRegistry]]>=
|
||||
static GUSIDeviceRegistry * Instance();
|
||||
// <Operations for [[GUSIDeviceRegistry]]>=
|
||||
GUSISocket * open(const char * path, int flags);
|
||||
// <Operations for [[GUSIDeviceRegistry]]>=
|
||||
int remove(const char * path);
|
||||
// <Operations for [[GUSIDeviceRegistry]]>=
|
||||
int rename(const char * oldname, const char * newname);
|
||||
// <Operations for [[GUSIDeviceRegistry]]>=
|
||||
int stat(const char * path, struct stat * buf, bool useAlias);
|
||||
// <Operations for [[GUSIDeviceRegistry]]>=
|
||||
int chmod(const char * path, mode_t mode);
|
||||
// <Operations for [[GUSIDeviceRegistry]]>=
|
||||
int utime(const char * path, const utimbuf * times);
|
||||
// <Operations for [[GUSIDeviceRegistry]]>=
|
||||
int access(const char * path, int mode);
|
||||
// <Operations for [[GUSIDeviceRegistry]]>=
|
||||
int mkdir(const char * path);
|
||||
// <Operations for [[GUSIDeviceRegistry]]>=
|
||||
int rmdir(const char * path);
|
||||
// <Operations for [[GUSIDeviceRegistry]]>=
|
||||
GUSIDirectory * opendir(const char * path);
|
||||
// <Operations for [[GUSIDeviceRegistry]]>=
|
||||
int symlink(const char * target, const char * newlink);
|
||||
// <Operations for [[GUSIDeviceRegistry]]>=
|
||||
int readlink(const char * path, char * buf, int bufsize);
|
||||
// <Operations for [[GUSIDeviceRegistry]]>=
|
||||
int fgetfileinfo(const char * path, OSType * creator, OSType * type);
|
||||
int fsetfileinfo(const char * path, OSType creator, OSType type);
|
||||
// <Operations for [[GUSIDeviceRegistry]]>=
|
||||
int faccess(const char * path, unsigned * cmd, void * arg);
|
||||
// [[AddDevice]] and [[RemoveDevice]] add and remove a [[GUSIDevice]].
|
||||
//
|
||||
// <Registration interface of [[GUSIDeviceRegistry]]>=
|
||||
void AddDevice(GUSIDevice * device);
|
||||
void RemoveDevice(GUSIDevice * device);
|
||||
// It is convenient to define iterators to iterate across all devices.
|
||||
//
|
||||
// <Iterator on [[GUSIDeviceRegistry]]>=
|
||||
class iterator;
|
||||
|
||||
iterator begin();
|
||||
iterator end();
|
||||
protected:
|
||||
// On construction, a [[GUSIFileToken]] looks up the appropriate device in the
|
||||
// [[GUSIDeviceRegistry]].
|
||||
//
|
||||
// <Looking up a device in the [[GUSIDeviceRegistry]]>=
|
||||
friend class GUSIFileToken;
|
||||
|
||||
GUSIDevice * Lookup(GUSIFileToken & file);
|
||||
private:
|
||||
// <Privatissima of [[GUSIDeviceRegistry]]>=
|
||||
static GUSIDeviceRegistry * sInstance;
|
||||
// Devices are stored in a linked list. On creation of the registry, it immediately
|
||||
// registers the instance for plain Macintosh file sockets, to which pretty much all
|
||||
// operations default. This device will never refuse any request.
|
||||
//
|
||||
// <Privatissima of [[GUSIDeviceRegistry]]>=
|
||||
GUSIDevice * fFirstDevice;
|
||||
GUSIDeviceRegistry();
|
||||
};
|
||||
// \section{Definition of [[GUSIDevice]]}
|
||||
//
|
||||
// [[GUSIDevice]] consists of a few maintenance functions and the
|
||||
// device operations. The request dispatcher first calls [[Want]] for
|
||||
// each candidate device and as soon as it's successful, calls the specific
|
||||
// operation. Devices are kept in a linked list by the [[GUSIDeviceRegistry]].
|
||||
//
|
||||
// <Definition of class [[GUSIDevice]]>=
|
||||
class GUSIDevice {
|
||||
public:
|
||||
virtual bool Want(GUSIFileToken & file);
|
||||
|
||||
// <Operations for [[GUSIDevice]]>=
|
||||
virtual GUSISocket * open(GUSIFileToken & file, int flags);
|
||||
// <Operations for [[GUSIDevice]]>=
|
||||
virtual int remove(GUSIFileToken & file);
|
||||
// <Operations for [[GUSIDevice]]>=
|
||||
virtual int rename(GUSIFileToken & from, const char * newname);
|
||||
// <Operations for [[GUSIDevice]]>=
|
||||
virtual int stat(GUSIFileToken & file, struct stat * buf);
|
||||
// <Operations for [[GUSIDevice]]>=
|
||||
virtual int chmod(GUSIFileToken & file, mode_t mode);
|
||||
// <Operations for [[GUSIDevice]]>=
|
||||
virtual int utime(GUSIFileToken & file, const utimbuf * times);
|
||||
// <Operations for [[GUSIDevice]]>=
|
||||
virtual int access(GUSIFileToken & file, int mode);
|
||||
// <Operations for [[GUSIDevice]]>=
|
||||
virtual int mkdir(GUSIFileToken & file);
|
||||
// <Operations for [[GUSIDevice]]>=
|
||||
virtual int rmdir(GUSIFileToken & file);
|
||||
// <Operations for [[GUSIDevice]]>=
|
||||
virtual GUSIDirectory * opendir(GUSIFileToken & file);
|
||||
// <Operations for [[GUSIDevice]]>=
|
||||
virtual int symlink(GUSIFileToken & to, const char * newlink);
|
||||
// <Operations for [[GUSIDevice]]>=
|
||||
virtual int readlink(GUSIFileToken & link, char * buf, int bufsize);
|
||||
// <Operations for [[GUSIDevice]]>=
|
||||
virtual int fgetfileinfo(GUSIFileToken & file, OSType * creator, OSType * type);
|
||||
virtual int fsetfileinfo(GUSIFileToken & file, OSType creator, OSType type);
|
||||
// <Operations for [[GUSIDevice]]>=
|
||||
virtual int faccess(GUSIFileToken & file, unsigned * cmd, void * arg);
|
||||
protected:
|
||||
friend class GUSIDeviceRegistry;
|
||||
friend class GUSIDeviceRegistry::iterator;
|
||||
|
||||
GUSIDevice() : fNextDevice(nil) {}
|
||||
virtual ~GUSIDevice() {}
|
||||
|
||||
GUSIDevice * fNextDevice;
|
||||
};
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=reset
|
||||
#endif
|
||||
|
||||
// \section{Implementation of [[GUSIDeviceRegistry]]}
|
||||
//
|
||||
//
|
||||
// <Definition of [[GUSISetupDevices]] hook>=
|
||||
extern "C" void GUSISetupDevices();
|
||||
|
||||
// <Inline member functions for class [[GUSIDeviceRegistry]]>=
|
||||
inline GUSIDeviceRegistry * GUSIDeviceRegistry::Instance()
|
||||
{
|
||||
if (!sInstance) {
|
||||
sInstance = new GUSIDeviceRegistry();
|
||||
GUSISetupDevices();
|
||||
}
|
||||
|
||||
return sInstance;
|
||||
}
|
||||
// The [[GUSIDeviceRegistry]] forward iterator is simple.
|
||||
//
|
||||
// <Inline member functions for class [[GUSIDeviceRegistry]]>=
|
||||
class GUSIDeviceRegistry::iterator {
|
||||
public:
|
||||
iterator(GUSIDevice * device = 0) : fDevice(device) {}
|
||||
GUSIDeviceRegistry::iterator & operator++()
|
||||
{ fDevice = fDevice->fNextDevice; return *this; }
|
||||
GUSIDeviceRegistry::iterator operator++(int)
|
||||
{ GUSIDeviceRegistry::iterator old(*this); fDevice = fDevice->fNextDevice; return old; }
|
||||
bool operator==(const GUSIDeviceRegistry::iterator other) const
|
||||
{ return fDevice==other.fDevice; }
|
||||
GUSIDevice & operator*() { return *fDevice; }
|
||||
GUSIDevice * operator->() { return fDevice; }
|
||||
private:
|
||||
GUSIDevice * fDevice;
|
||||
};
|
||||
|
||||
inline GUSIDeviceRegistry::iterator GUSIDeviceRegistry::begin()
|
||||
{
|
||||
return GUSIDeviceRegistry::iterator(fFirstDevice);
|
||||
}
|
||||
|
||||
inline GUSIDeviceRegistry::iterator GUSIDeviceRegistry::end()
|
||||
{
|
||||
return GUSIDeviceRegistry::iterator();
|
||||
}
|
||||
|
||||
#endif /* GUSI_SOURCE */
|
||||
|
||||
#endif /* _GUSIDevice_ */
|
|
@ -1,222 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSIDiag.nw - Assertions and diagnostics
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:10 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.12 2000/06/12 04:20:58 neeri
|
||||
// % Introduce GUSI_*printf
|
||||
// %
|
||||
// % Revision 1.11 2000/05/23 06:58:04 neeri
|
||||
// % Improve formatting
|
||||
// %
|
||||
// % Revision 1.10 1999/08/26 05:45:01 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.9 1999/08/02 07:02:43 neeri
|
||||
// % Support for asynchronous errors and other socket options
|
||||
// %
|
||||
// % Revision 1.8 1999/05/29 06:26:42 neeri
|
||||
// % Fixed header guards
|
||||
// %
|
||||
// % Revision 1.7 1999/04/10 04:45:47 neeri
|
||||
// % Add DCon stubs
|
||||
// %
|
||||
// % Revision 1.6 1999/03/17 09:05:07 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// % Revision 1.5 1999/02/25 03:49:00 neeri
|
||||
// % Switched to DCon for logging
|
||||
// %
|
||||
// % Revision 1.4 1998/01/25 20:53:53 neeri
|
||||
// % Engine implemented, except for signals & scheduling
|
||||
// %
|
||||
// % Revision 1.3 1996/12/16 02:17:20 neeri
|
||||
// % Tune messages
|
||||
// %
|
||||
// % Revision 1.2 1996/11/24 12:52:07 neeri
|
||||
// % Added GUSIPipeSockets
|
||||
// %
|
||||
// % Revision 1.1.1.1 1996/11/03 02:43:32 neeri
|
||||
// % Imported into CVS
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{Assertions and diagnostic messages}
|
||||
//
|
||||
// GUSI reports on three kinds of error conditions:
|
||||
//
|
||||
// \begin{itemize}
|
||||
// \item {\bf Internal} errors are usually caused by bugs in GUSI. They should be
|
||||
// considered fatal.
|
||||
// \item {\bf Client} errors are caused by calling GUSI routines with bad
|
||||
// parameters. They are typically handled by returning an appropriate error
|
||||
// code.
|
||||
// \item {\bf External} errors are caused by various OS and Network related
|
||||
// problems. Typically, they are also handled by returning an appropriate
|
||||
// error code.
|
||||
// \end{itemize}
|
||||
//
|
||||
// If you feel lucky, you can turn off the checking for internal and client errors,
|
||||
// but external errors will always be checked.
|
||||
//
|
||||
// <GUSIDiag.h>=
|
||||
#ifndef _GUSIDiag_
|
||||
#define _GUSIDiag_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <MacTypes.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
// \section{Definition of diagnostics}
|
||||
//
|
||||
// Depending on the diagnostic level, messages get printed to the DCon console.
|
||||
//
|
||||
// <Definition of diagnostic logfile>=
|
||||
extern char * GUSI_diag_log;
|
||||
// Printing is done by passing an argument list to [[GUSI_log]]. To simplify the job
|
||||
// for the diagnostic macros, [[GUSI_log]] returns a [[bool]] value which is
|
||||
// always [[false]]. [[GUSI_break]] stops with a [[DebugStr]] call. [[GUSI_pos]]
|
||||
// establishes the source code position for diagnostic messages.
|
||||
// instead of logging.
|
||||
//
|
||||
// <Definition of diagnostic logfile>=
|
||||
bool GUSI_pos(const char * file, int line);
|
||||
bool GUSI_log(const char * format, ...);
|
||||
bool GUSI_break(const char * format, ...);
|
||||
// There are four levels of diagnostic handling:
|
||||
// \begin{itemize}
|
||||
// \item [[GUSI_DIAG_RECKLESS]] totally ignores all internal and client errors. This
|
||||
// setting is not recommended.
|
||||
// \item [[GUSI_DIAG_RELAXED]] ignores internal errors, but checks client errors. This
|
||||
// setting is probably the best for production code.
|
||||
// \item [[GUSI_DIAG_CAUTIOUS]] checks and logs internal and client errors. This
|
||||
// setting is best for GUSI client development.
|
||||
// \item [[GUSI_DIAG_PARANOID]] immediately stops at internal errors, checks and
|
||||
// logs client and external errors. This is the preferred setting for GUSI
|
||||
// internal development.
|
||||
// \end{itemize}
|
||||
//
|
||||
//
|
||||
// <Definition of diagnostic levels>=
|
||||
#define GUSI_DIAG_RECKLESS 0
|
||||
#define GUSI_DIAG_RELAXED 1
|
||||
#define GUSI_DIAG_CAUTIOUS 2
|
||||
#define GUSI_DIAG_PARANOID 3
|
||||
// [[GUSI_DIAG]] is defined to the diagnostic level. It can be overridden on a
|
||||
// module by module basis, or by changing the default setting here.
|
||||
// [[GUSI_MESSAGE_LEVEL]] determines how important a message has to be to print it.
|
||||
// [[GUSI_LOG_POS]] determines whether we want to log the code position.
|
||||
//
|
||||
// <Definition of diagnostic levels>=
|
||||
#ifndef GUSI_DIAG
|
||||
#define GUSI_DIAG GUSI_DIAG_PARANOID
|
||||
#endif
|
||||
#ifndef GUSI_LOG_POS
|
||||
#define GUSI_LOG_POS 0
|
||||
#endif
|
||||
#ifndef GUSI_MESSAGE_LEVEL
|
||||
#define GUSI_MESSAGE_LEVEL 3
|
||||
#endif
|
||||
// <Definition of diagnostics>=
|
||||
#if GUSI_LOG_POS
|
||||
#define GUSI_POS GUSI_pos(__FILE__, __LINE__)
|
||||
#define GUSI_LOG GUSI_POS || GUSI_log
|
||||
#else
|
||||
#define GUSI_LOG GUSI_log
|
||||
#endif
|
||||
#define GUSI_BREAK GUSI_break
|
||||
// <Definition of diagnostics>=
|
||||
#if GUSI_DIAG == GUSI_DIAG_RECKLESS
|
||||
// [[GUSI_DIAG_RECKLESS]] only checks for external errors.
|
||||
//
|
||||
// <Diagnostics for [[GUSI_DIAG_RECKLESS]]>=
|
||||
#define GUSI_ASSERT_INTERNAL(COND, ARGLIST) true
|
||||
#define GUSI_ASSERT_CLIENT(COND, ARGLIST) true
|
||||
#define GUSI_ASSERT_EXTERNAL(COND, ARGLIST) (COND)
|
||||
#define GUSI_SASSERT_INTERNAL(COND, MSG) true
|
||||
#define GUSI_SASSERT_CLIENT(COND, MSG) true
|
||||
#define GUSI_SASSERT_EXTERNAL(COND, MSG) (COND)
|
||||
#elif GUSI_DIAG == GUSI_DIAG_RELAXED
|
||||
// [[GUSI_DIAG_RELAXED]] ignores internal errors, but checks client errors.
|
||||
//
|
||||
// <Diagnostics for [[GUSI_DIAG_RELAXED]]>=
|
||||
#define GUSI_ASSERT_INTERNAL(COND, ARGLIST) true
|
||||
#define GUSI_ASSERT_CLIENT(COND, ARGLIST) (COND)
|
||||
#define GUSI_ASSERT_EXTERNAL(COND, ARGLIST) (COND)
|
||||
#define GUSI_SASSERT_INTERNAL(COND, MSG) true
|
||||
#define GUSI_SASSERT_CLIENT(COND, MSG) (COND)
|
||||
#define GUSI_SASSERT_EXTERNAL(COND, MSG) (COND)
|
||||
#elif GUSI_DIAG == GUSI_DIAG_CAUTIOUS
|
||||
// [[GUSI_DIAG_CAUTIOUS]] checks and logs internal and client errors.
|
||||
//
|
||||
// <Diagnostics for [[GUSI_DIAG_CAUTIOUS]]>=
|
||||
#define GUSI_ASSERT_INTERNAL(COND, ARGLIST) ((COND) || GUSI_LOG ARGLIST)
|
||||
#define GUSI_ASSERT_CLIENT(COND, ARGLIST) ((COND) || GUSI_LOG ARGLIST)
|
||||
#define GUSI_ASSERT_EXTERNAL(COND, ARGLIST) (COND)
|
||||
#define GUSI_SASSERT_INTERNAL(COND, MSG) ((COND) || GUSI_LOG ("%s", MSG))
|
||||
#define GUSI_SASSERT_CLIENT(COND, MSG) ((COND) || GUSI_LOG ("%s", MSG))
|
||||
#define GUSI_SASSERT_EXTERNAL(COND, MSG) (COND)
|
||||
#elif GUSI_DIAG == GUSI_DIAG_PARANOID
|
||||
// [[GUSI_DIAG_PARANOID]] immediately stops at internal errors, checks and
|
||||
// logs client and external errors.
|
||||
//
|
||||
// <Diagnostics for [[GUSI_DIAG_PARANOID]]>=
|
||||
#define GUSI_ASSERT_INTERNAL(COND, ARGLIST) ((COND) || GUSI_BREAK ARGLIST)
|
||||
#define GUSI_ASSERT_CLIENT(COND, ARGLIST) ((COND) || GUSI_LOG ARGLIST)
|
||||
#define GUSI_ASSERT_EXTERNAL(COND, ARGLIST) ((COND) || GUSI_LOG ARGLIST)
|
||||
#define GUSI_SASSERT_INTERNAL(COND, MSG) ((COND) || GUSI_BREAK ("%s", (MSG)))
|
||||
#define GUSI_SASSERT_CLIENT(COND, MSG) ((COND) || GUSI_LOG ("%s", MSG))
|
||||
#define GUSI_SASSERT_EXTERNAL(COND, MSG) ((COND) || GUSI_LOG ("%s", MSG))
|
||||
#else
|
||||
#error "GUSI_DIAG defined to illegal value: " GUSI_DIAG
|
||||
#endif
|
||||
// There are 11 different diagnostic macros. [[GUSI_ASSERT_INTERNAL]],
|
||||
// [[GUSI_ASSERT_CLIENT]] and [[GUSI_ASSERT_EXTERNAL]] check for internal,
|
||||
// client, and external errors, respectively. Their first argument is a
|
||||
// conditional expression which when [[false]] indicates that an error
|
||||
// happened. [[GUSI_MESSAGE]] has the same logging status as
|
||||
// [[GUSI_ASSERT_EXTERNAL]], but does not check any conditions. The [[SASSERT]]
|
||||
// and [[SMESSAGE]] variants do the same checking, but only take a simple
|
||||
// message instead of an argument list. The [[CASSERT]] variants simply output
|
||||
// the condition as the message.
|
||||
//
|
||||
// <Definition of diagnostics>=
|
||||
#define GUSI_CASSERT_INTERNAL(COND) \
|
||||
GUSI_SASSERT_INTERNAL(COND, "(" #COND ") -- assertion failed.\n" )
|
||||
#define GUSI_CASSERT_CLIENT(COND) \
|
||||
GUSI_SASSERT_CLIENT(COND, "(" #COND ") -- assertion failed.\n" )
|
||||
#define GUSI_CASSERT_EXTERNAL(COND) \
|
||||
GUSI_SASSERT_EXTERNAL(COND, "(" #COND ") -- assertion failed.\n" )
|
||||
#define GUSI_MESSAGE1(ARGLIST) \
|
||||
GUSI_ASSERT_EXTERNAL(GUSI_MESSAGE_LEVEL>1, ARGLIST)
|
||||
#define GUSI_SMESSAGE1(MSG) \
|
||||
GUSI_SASSERT_EXTERNAL(GUSI_MESSAGE_LEVEL>1, MSG)
|
||||
#define GUSI_MESSAGE2(ARGLIST) \
|
||||
GUSI_ASSERT_EXTERNAL(GUSI_MESSAGE_LEVEL>2, ARGLIST)
|
||||
#define GUSI_SMESSAGE2(MSG) \
|
||||
GUSI_SASSERT_EXTERNAL(GUSI_MESSAGE_LEVEL>2, MSG)
|
||||
#define GUSI_MESSAGE3(ARGLIST) \
|
||||
GUSI_ASSERT_EXTERNAL(GUSI_MESSAGE_LEVEL>3, ARGLIST)
|
||||
#define GUSI_SMESSAGE3(MSG) \
|
||||
GUSI_SASSERT_EXTERNAL(GUSI_MESSAGE_LEVEL>3, MSG)
|
||||
#define GUSI_MESSAGE4(ARGLIST) \
|
||||
GUSI_ASSERT_EXTERNAL(GUSI_MESSAGE_LEVEL>4, ARGLIST)
|
||||
#define GUSI_SMESSAGE4(MSG) \
|
||||
GUSI_SASSERT_EXTERNAL(GUSI_MESSAGE_LEVEL>4, MSG)
|
||||
#define GUSI_MESSAGE5(ARGLIST) \
|
||||
GUSI_ASSERT_EXTERNAL(GUSI_MESSAGE_LEVEL>5, ARGLIST)
|
||||
#define GUSI_SMESSAGE5(MSG) \
|
||||
GUSI_SASSERT_EXTERNAL(GUSI_MESSAGE_LEVEL>5, MSG)
|
||||
#define GUSI_MESSAGE(ARGLIST) GUSI_MESSAGE3(ARGLIST)
|
||||
#define GUSI_SMESSAGE(MSG) GUSI_SMESSAGE3(MSG)
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _GUSIDiag_ */
|
|
@ -1,113 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSIFSWrappers.nw - Pseudo-synchronous file calls
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.8 2001/07/23 06:31:37 neeri
|
||||
// % Use PBXGetVolInfoSync to get correct block size for stat() (MacPerl Bug #424874)
|
||||
// %
|
||||
// % Revision 1.7 2001/01/17 08:45:49 neeri
|
||||
// % Make open calls synchronous
|
||||
// %
|
||||
// % Revision 1.6 2000/05/23 06:58:04 neeri
|
||||
// % Improve formatting
|
||||
// %
|
||||
// % Revision 1.5 2000/01/17 01:41:52 neeri
|
||||
// % Handle special cases in FSMoveRename
|
||||
// %
|
||||
// % Revision 1.4 1999/08/26 05:45:01 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.3 1999/07/19 06:21:02 neeri
|
||||
// % Add mkdir/rmdir, fix various file manager related bugs
|
||||
// %
|
||||
// % Revision 1.2 1999/05/30 02:16:54 neeri
|
||||
// % Cleaner definition of GUSICatInfo
|
||||
// %
|
||||
// % Revision 1.1 1998/10/11 16:45:14 neeri
|
||||
// % Ready to release 2.0a2
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{Pseudo-synchronous File System Calls}
|
||||
//
|
||||
// MacOS offers a wide variety of file system APIs, but the most convenient
|
||||
// of them--the [[FSpXXX]] calls only works synchronously. The routines defined
|
||||
// here offer a version of these calls, executed asynchronously and embedded
|
||||
// into the [[GUSIContext]] switching model.
|
||||
//
|
||||
// <GUSIFSWrappers.h>=
|
||||
#ifndef _GUSIFSWrappers_
|
||||
#define _GUSIFSWrappers_
|
||||
|
||||
#ifdef GUSI_SOURCE
|
||||
|
||||
#include <Files.h>
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#include "GUSIFileSpec.h"
|
||||
|
||||
__BEGIN_DECLS
|
||||
// <Declarations of C [[GUSIFSWrappers]]>=
|
||||
OSErr GUSIFSOpenDriver(StringPtr name, short * refNum);
|
||||
// <Declarations of C [[GUSIFSWrappers]]>=
|
||||
OSErr GUSIFSGetFInfo(const FSSpec * spec, FInfo * info);
|
||||
OSErr GUSIFSSetFInfo(const FSSpec * spec, const FInfo * info);
|
||||
// <Declarations of C [[GUSIFSWrappers]]>=
|
||||
OSErr GUSIFSOpenDF(const FSSpec * spec, char permission, short * refNum);
|
||||
OSErr GUSIFSOpenRF(const FSSpec * spec, char permission, short * refNum);
|
||||
// <Declarations of C [[GUSIFSWrappers]]>=
|
||||
OSErr GUSIFSGetVolParms(short vRefNum, GetVolParmsInfoBuffer * volParms);
|
||||
// <Declarations of C [[GUSIFSWrappers]]>=
|
||||
OSErr GUSIFSCreate(const FSSpec * spec, OSType creator, OSType type, ScriptCode script);
|
||||
// <Declarations of C [[GUSIFSWrappers]]>=
|
||||
OSErr GUSIFSDelete(const FSSpec * spec);
|
||||
// <Declarations of C [[GUSIFSWrappers]]>=
|
||||
OSErr GUSIFSDirCreate(const FSSpec * spec);
|
||||
// <Declarations of C [[GUSIFSWrappers]]>=
|
||||
OSErr GUSIFSSetFLock(const FSSpec * spec);
|
||||
OSErr GUSIFSRstFLock(const FSSpec * spec);
|
||||
// <Declarations of C [[GUSIFSWrappers]]>=
|
||||
OSErr GUSIFSRename(const FSSpec * spec, ConstStr255Param newname);
|
||||
// <Declarations of C [[GUSIFSWrappers]]>=
|
||||
OSErr GUSIFSCatMove(const FSSpec * spec, const FSSpec * dest);
|
||||
// <Declarations of C [[GUSIFSWrappers]]>=
|
||||
OSErr GUSIFSMoveRename(const FSSpec * spec, const FSSpec * dest);
|
||||
__END_DECLS
|
||||
#ifdef __cplusplus
|
||||
// <Declarations of C++ [[GUSIFSWrappers]]>=
|
||||
OSErr GUSIFSGetCatInfo(GUSIIOPBWrapper<GUSICatInfo> * info);
|
||||
OSErr GUSIFSSetCatInfo(GUSIIOPBWrapper<GUSICatInfo> * info);
|
||||
// <Declarations of C++ [[GUSIFSWrappers]]>=
|
||||
OSErr GUSIFSGetFCBInfo(GUSIIOPBWrapper<FCBPBRec> * fcb);
|
||||
// <Declarations of C++ [[GUSIFSWrappers]]>=
|
||||
OSErr GUSIFSGetVInfo(GUSIIOPBWrapper<ParamBlockRec> * pb);
|
||||
OSErr GUSIFSHGetVInfo(GUSIIOPBWrapper<HParamBlockRec> * pb);
|
||||
// According to Andreas Grosam, [[PBOpenAsync]] may cause the file not to be closed properly when the
|
||||
// process quits, so we call that call synchronously.
|
||||
//
|
||||
// <Declarations of C++ [[GUSIFSWrappers]]>=
|
||||
OSErr GUSIFSOpen(GUSIIOPBWrapper<ParamBlockRec> * pb);
|
||||
// <Declarations of C++ [[GUSIFSWrappers]]>=
|
||||
OSErr GUSIFSHGetFInfo(GUSIIOPBWrapper<HParamBlockRec> * pb);
|
||||
OSErr GUSIFSHSetFInfo(GUSIIOPBWrapper<HParamBlockRec> * pb);
|
||||
// <Declarations of C++ [[GUSIFSWrappers]]>=
|
||||
OSErr GUSIFSHGetVolParms(GUSIIOPBWrapper<HParamBlockRec> * pb);
|
||||
// <Declarations of C++ [[GUSIFSWrappers]]>=
|
||||
OSErr GUSIFSCreate(const FSSpec * spec);
|
||||
// <Declarations of C++ [[GUSIFSWrappers]]>=
|
||||
OSErr GUSIFSCatMove(const FSSpec * spec, long dest);
|
||||
// Getting the correct allocation block size can be sort of tricky. [[PBHGetVInfoAsync]] returns
|
||||
// a value tweaked to allow free space calculations on large volumes, so we have to walk the
|
||||
// fcb queue to get a legitimate value.
|
||||
//
|
||||
// <Declarations of C++ [[GUSIFSWrappers]]>=
|
||||
OSErr GUSIFSXGetVolInfo(GUSIIOPBWrapper<XVolumeParam> * pb);
|
||||
#endif
|
||||
|
||||
#endif /* GUSI_SOURCE */
|
||||
|
||||
#endif /* GUSIFSWrappers */
|
|
@ -1,203 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSIFactory.nw - Socket factories
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:10 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.10 2000/05/23 07:00:00 neeri
|
||||
// % Improve formatting
|
||||
// %
|
||||
// % Revision 1.9 2000/03/15 07:22:07 neeri
|
||||
// % Enforce alignment choices
|
||||
// %
|
||||
// % Revision 1.8 1999/11/15 07:27:18 neeri
|
||||
// % Getting ready for GUSI 2.0.1
|
||||
// %
|
||||
// % Revision 1.7 1999/08/26 05:45:02 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.6 1999/05/29 06:26:43 neeri
|
||||
// % Fixed header guards
|
||||
// %
|
||||
// % Revision 1.5 1998/11/22 23:06:53 neeri
|
||||
// % Releasing 2.0a4 in a hurry
|
||||
// %
|
||||
// % Revision 1.4 1998/10/25 11:37:37 neeri
|
||||
// % More configuration hooks
|
||||
// %
|
||||
// % Revision 1.3 1998/08/02 11:20:08 neeri
|
||||
// % Fixed some typos
|
||||
// %
|
||||
// % Revision 1.2 1998/01/25 20:53:54 neeri
|
||||
// % Engine implemented, except for signals & scheduling
|
||||
// %
|
||||
// % Revision 1.1 1996/12/16 02:12:40 neeri
|
||||
// % TCP Sockets sort of work
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{Socket Factories}
|
||||
//
|
||||
// Instead of creating sockets of some specific subtype of [[GUSISocket]],
|
||||
// directly, we choose the more flexible approach of creating them in
|
||||
// some instance of a subtype of the abstract factory class [[GUSISocketFactory]].
|
||||
// For even more flexibility and a direct mapping to BSD socket domains,
|
||||
// [[GUSISocketFactory]] instances are collected in a [[GUSISocketDomainRegistry]].
|
||||
// If several types and or protocols in a domain are implemented, they are collected
|
||||
// in a [[GUSISocketTypeRegistry]].
|
||||
//
|
||||
// <GUSIFactory.h>=
|
||||
#ifndef _GUSIFactory_
|
||||
#define _GUSIFactory_
|
||||
|
||||
#ifdef GUSI_SOURCE
|
||||
|
||||
#include "GUSISocket.h"
|
||||
|
||||
#include <ConditionalMacros.h>
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=native
|
||||
#endif
|
||||
|
||||
// \section{Definition of [[GUSISocketFactory]]}
|
||||
//
|
||||
// [[GUSISocketFactory]] consists of a few maintenance functions and the socket
|
||||
// operations.
|
||||
//
|
||||
// <Definition of class [[GUSISocketFactory]]>=
|
||||
class GUSISocketFactory {
|
||||
public:
|
||||
virtual int socketpair(int domain, int type, int protocol, GUSISocket * s[2]);
|
||||
virtual GUSISocket * socket(int domain, int type, int protocol) = 0;
|
||||
protected:
|
||||
GUSISocketFactory() {}
|
||||
virtual ~GUSISocketFactory() {}
|
||||
};
|
||||
// \section{Definition of [[GUSISocketDomainRegistry]]}
|
||||
//
|
||||
// The [[GUSISocketDomainRegistry]] is a singleton class registering all socket
|
||||
// domains.
|
||||
//
|
||||
// <Definition of class [[GUSISocketDomainRegistry]]>=
|
||||
class GUSISocketDomainRegistry : public GUSISocketFactory {
|
||||
public:
|
||||
// The only instance of [[GUSISocketDomainRegistry]] is, as usual, obtained by calling
|
||||
// [[Instance]]. Calling [[socket]] on this instance will then create a socket.
|
||||
//
|
||||
// <Socket creation interface of [[GUSISocketDomainRegistry]]>=
|
||||
virtual GUSISocket * socket(int domain, int type, int protocol);
|
||||
virtual int socketpair(int domain, int type, int protocol, GUSISocket * s[2]);
|
||||
static GUSISocketDomainRegistry * Instance();
|
||||
// [[AddFactory]] and [[RemoveFactory]] add and remove a [[GUSISocketFactory]]
|
||||
// for a given domain number. Both return the previous registrant.
|
||||
//
|
||||
// <Registration interface of [[GUSISocketDomainRegistry]]>=
|
||||
GUSISocketFactory * AddFactory(int domain, GUSISocketFactory * factory);
|
||||
GUSISocketFactory * RemoveFactory(int domain);
|
||||
private:
|
||||
// <Privatissima of [[GUSISocketDomainRegistry]]>=
|
||||
static GUSISocketDomainRegistry * sInstance;
|
||||
// We store domain factories in a table that is quite comfortably sized.
|
||||
//
|
||||
// <Privatissima of [[GUSISocketDomainRegistry]]>=
|
||||
GUSISocketFactory * factory[AF_MAX];
|
||||
GUSISocketDomainRegistry();
|
||||
};
|
||||
// \section{Definition of [[GUSISocketTypeRegistry]]}
|
||||
//
|
||||
// A [[GUSISocketTypeRegistry]] registers factories for some domain by type and
|
||||
// protocol.
|
||||
//
|
||||
// <Definition of class [[GUSISocketTypeRegistry]]>=
|
||||
class GUSISocketTypeRegistry : public GUSISocketFactory {
|
||||
public:
|
||||
// [[GUSISocketTypeRegistry]] is not a singleton, but each instance is somewhat
|
||||
// singletonish in that it does some delayed initialization only when it's used
|
||||
// and at that point registers itself with the [[GUSISocketDomainRegistry]].
|
||||
// Calling [[socket]] on these instances will then create a socket.
|
||||
//
|
||||
// <Socket creation interface of [[GUSISocketTypeRegistry]]>=
|
||||
GUSISocketTypeRegistry(int domain, int maxfactory);
|
||||
virtual GUSISocket * socket(int domain, int type, int protocol);
|
||||
virtual int socketpair(int domain, int type, int protocol, GUSISocket * s[2]);
|
||||
// [[AddFactory]] and [[RemoveFactory]] add and remove a [[GUSISocketFactory]]
|
||||
// for a given type and protocol (both of which can be specified as 0 to match any
|
||||
// value). Both return the previous registrant.
|
||||
//
|
||||
// <Registration interface of [[GUSISocketTypeRegistry]]>=
|
||||
GUSISocketFactory * AddFactory(int type, int protocol, GUSISocketFactory * factory);
|
||||
GUSISocketFactory * RemoveFactory(int type, int protocol);
|
||||
private:
|
||||
// \section{Implementation of [[GUSISocketTypeRegistry]]}
|
||||
//
|
||||
// We store type factories in a fixed size table. This table is only
|
||||
// initialized when any non-constructor public member is called.
|
||||
//
|
||||
// <Privatissima of [[GUSISocketTypeRegistry]]>=
|
||||
struct Entry {
|
||||
int type;
|
||||
int protocol;
|
||||
GUSISocketFactory * factory;
|
||||
Entry() : type(0), protocol(0), factory(nil) {}
|
||||
};
|
||||
Entry * factory;
|
||||
int domain;
|
||||
int maxfactory;
|
||||
// [[Initialize]] initializes the table and registers the object with the
|
||||
// [[GUSISocketDomainRegistry]] the first time it's called.
|
||||
//
|
||||
// <Privatissima of [[GUSISocketTypeRegistry]]>=
|
||||
void Initialize();
|
||||
// Unlike for a [[GUSISocketDomainRegistry]], match identification for a
|
||||
// [[GUSISocketTypeRegistry]] takes a linear search. [[Find]] stops
|
||||
// when it has found either a match or an empty slot.
|
||||
//
|
||||
// <Privatissima of [[GUSISocketTypeRegistry]]>=
|
||||
bool Find(int type, int protocol, bool exact, Entry *&found);
|
||||
};
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=reset
|
||||
#endif
|
||||
|
||||
// \section{Implementation of [[GUSISocketDomainRegistry]]}
|
||||
//
|
||||
// By now, you should know how singletons are created. Could it be that the
|
||||
// combination of Design Patterns and Literate Programming leads to a
|
||||
// proliferation of cliches?
|
||||
//
|
||||
// <Definition of [[GUSISetupFactories]] hook>=
|
||||
extern "C" void GUSISetupFactories();
|
||||
|
||||
// <Inline member functions for class [[GUSISocketDomainRegistry]]>=
|
||||
inline GUSISocketDomainRegistry * GUSISocketDomainRegistry::Instance()
|
||||
{
|
||||
if (!sInstance) {
|
||||
sInstance = new GUSISocketDomainRegistry();
|
||||
GUSISetupFactories();
|
||||
}
|
||||
|
||||
return sInstance;
|
||||
}
|
||||
// [[RemoveFactory]] can actually be implemented in terms of [[AddFactory]] but
|
||||
// that might confuse readers.
|
||||
//
|
||||
// <Inline member functions for class [[GUSISocketDomainRegistry]]>=
|
||||
inline GUSISocketFactory * GUSISocketDomainRegistry::RemoveFactory(int domain)
|
||||
{
|
||||
return AddFactory(domain, nil);
|
||||
}
|
||||
// <Inline member functions for class [[GUSISocketTypeRegistry]]>=
|
||||
inline GUSISocketTypeRegistry::GUSISocketTypeRegistry(int domain, int maxfactory)
|
||||
: domain(domain), maxfactory(maxfactory), factory(nil)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* GUSI_SOURCE */
|
||||
|
||||
#endif /* _GUSIFactory_ */
|
|
@ -1,599 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSIFileSpec.nw - File specifications
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.19 2001/04/16 01:50:02 neeri
|
||||
// % Fix GUSIFSpGetCatInfo (MacPerl bug #232702); Fix parsing of absolute paths with embedded aliases.
|
||||
// %
|
||||
// % Revision 1.18 2001/04/01 07:40:15 neeri
|
||||
// % Fix :::paths (MacPerl Bug #409940)
|
||||
// %
|
||||
// % Revision 1.17 2001/03/20 02:34:22 neeri
|
||||
// % Commented out false friends
|
||||
// %
|
||||
// % Revision 1.16 2001/03/09 09:20:53 neeri
|
||||
// % Fixed major bugs in relative path generation
|
||||
// %
|
||||
// % Revision 1.15 2001/01/17 08:46:45 neeri
|
||||
// % Get rid of excess directory seperators when name is empty
|
||||
// %
|
||||
// % Revision 1.14 2000/12/23 06:10:17 neeri
|
||||
// % Add GUSIFSpTouchFolder, GUSIFSpGetCatInfo; copy error in copy constructor
|
||||
// %
|
||||
// % Revision 1.13 2000/10/16 03:59:36 neeri
|
||||
// % Make FSSpec a member of GUSIFileSpec instead of a base class
|
||||
// %
|
||||
// % Revision 1.12 2000/06/12 04:20:58 neeri
|
||||
// % Introduce GUSI_*printf
|
||||
// %
|
||||
// % Revision 1.11 2000/05/23 07:00:00 neeri
|
||||
// % Improve formatting
|
||||
// %
|
||||
// % Revision 1.10 2000/03/15 07:16:08 neeri
|
||||
// % Fix path construction, temp name bugs
|
||||
// %
|
||||
// % Revision 1.9 2000/03/06 06:34:11 neeri
|
||||
// % Added C FSSpec convenience calls
|
||||
// %
|
||||
// % Revision 1.8 1999/08/26 05:45:02 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.7 1999/07/19 06:21:02 neeri
|
||||
// % Add mkdir/rmdir, fix various file manager related bugs
|
||||
// %
|
||||
// % Revision 1.6 1999/06/28 06:00:53 neeri
|
||||
// % add support for generating temp names from basename
|
||||
// %
|
||||
// % Revision 1.5 1999/05/30 02:16:53 neeri
|
||||
// % Cleaner definition of GUSICatInfo
|
||||
// %
|
||||
// % Revision 1.4 1999/03/17 09:05:07 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// % Revision 1.3 1998/10/11 16:45:15 neeri
|
||||
// % Ready to release 2.0a2
|
||||
// %
|
||||
// % Revision 1.2 1998/08/01 21:32:04 neeri
|
||||
// % About ready for 2.0a1
|
||||
// %
|
||||
// % Revision 1.1 1998/01/25 21:02:46 neeri
|
||||
// % Engine implemented, except for signals & scheduling
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{File specifications}
|
||||
//
|
||||
// While the Macintosh toolbox has a convenient type [[FSSpec]] to pass to
|
||||
// file system routines, it lacks manipulation functions. We provide them here.
|
||||
// This module has been known under a different name and with different data types
|
||||
// in GUSI 1.
|
||||
//
|
||||
// <GUSIFileSpec.h>=
|
||||
#ifndef _GUSIFileSpec_
|
||||
#define _GUSIFileSpec_
|
||||
|
||||
#include <MacTypes.h>
|
||||
#include <Files.h>
|
||||
#include <Folders.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
// \section{C Interfaces to [[GUSIFileSpec]]}
|
||||
//
|
||||
// Many of the API routines defined here are useful to C code and not too hard to make accessible,
|
||||
// even though I prefer the C++ versions. As opposed to GUSI 1, we stick to our namespace now.
|
||||
//
|
||||
// <Plain C interfaces to [[GUSIFileSpec]]>=
|
||||
/*
|
||||
* Construct a FSSpec from...
|
||||
*/
|
||||
/* ... the refNum of an open file. */
|
||||
OSErr GUSIFRefNum2FSp(short fRefNum, FSSpec * desc);
|
||||
/* ... a working directory & file name. */
|
||||
OSErr GUSIWD2FSp(short wd, ConstStr31Param name, FSSpec * desc);
|
||||
/* ... a path name. */
|
||||
OSErr GUSIPath2FSp(const char * path, FSSpec * desc);
|
||||
/* ... a special object. */
|
||||
OSErr GUSISpecial2FSp(OSType object, short vol, FSSpec * desc);
|
||||
/* ... a temporary file path. */
|
||||
OSErr GUSIMakeTempFSp(short vol, long dirID, FSSpec * desc);
|
||||
|
||||
/*
|
||||
* Convert a FSSpec into...
|
||||
*/
|
||||
/* ... a full path name. */
|
||||
char * GUSIFSp2FullPath(const FSSpec * desc);
|
||||
/* ... a relative path name if possible, full if not */
|
||||
char * GUSIFSp2RelPath(const FSSpec * desc);
|
||||
/* ... a path relative to the specified directory */
|
||||
char * GUSIFSp2DirRelPath(const FSSpec * desc, const FSSpec * dir);
|
||||
/* ... an GUSI-=specific ASCII encoding. */
|
||||
char * GUSIFSp2Encoding(const FSSpec * desc);
|
||||
|
||||
/*
|
||||
* Construct FSSpec of...
|
||||
*/
|
||||
/* ... (vRefNum, parID) */
|
||||
OSErr GUSIFSpUp(FSSpec * desc);
|
||||
/* ... file (name) in directory denoted by desc */
|
||||
OSErr GUSIFSpDown(FSSpec * desc, ConstStr31Param name);
|
||||
/* ... of nth file in directory denoted by (vRefNum, parID) */
|
||||
OSErr GUSIFSpIndex(FSSpec * desc, short n);
|
||||
|
||||
/* Resolve if alias file */
|
||||
OSErr GUSIFSpResolve(FSSpec * spec);
|
||||
|
||||
/* Touch folder containing the object */
|
||||
OSErr GUSIFSpTouchFolder(const FSSpec * spec);
|
||||
|
||||
/* Get catalog information (after resolving leaf aliases) */
|
||||
OSErr GUSIFSpGetCatInfo(FSSpec * spec, CInfoPBRec * info);
|
||||
__END_DECLS
|
||||
|
||||
#ifdef GUSI_SOURCE
|
||||
|
||||
#include "GUSIBasics.h"
|
||||
#include "GUSIContext.h"
|
||||
|
||||
#include <ConditionalMacros.h>
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=native
|
||||
#endif
|
||||
|
||||
// \section{Definition of [[GUSICatInfo]]}
|
||||
//
|
||||
// [[GUSICatInfo]] is a wrapper for [[CInfoPBRec]]. Since the latter is a [[union]], we cannot
|
||||
// inherit from it.
|
||||
//
|
||||
// <Definition of class [[GUSICatInfo]]>=
|
||||
class GUSICatInfo {
|
||||
CInfoPBRec fInfo;
|
||||
public:
|
||||
bool IsFile() const;
|
||||
bool IsAlias() const;
|
||||
bool DirIsExported() const;
|
||||
bool DirIsMounted() const;
|
||||
bool DirIsShared() const;
|
||||
bool HasRdPerm() const;
|
||||
bool HasWrPerm() const;
|
||||
bool Locked() const;
|
||||
|
||||
CInfoPBRec & Info() { return fInfo; }
|
||||
operator CInfoPBRec &() { return fInfo; }
|
||||
struct HFileInfo & FileInfo() { return fInfo.hFileInfo; }
|
||||
struct DirInfo & DirInfo() { return fInfo.dirInfo; }
|
||||
struct FInfo & FInfo() { return fInfo.hFileInfo.ioFlFndrInfo; }
|
||||
struct FXInfo & FXInfo() { return fInfo.hFileInfo.ioFlXFndrInfo; }
|
||||
|
||||
const CInfoPBRec & Info() const { return fInfo; }
|
||||
operator const CInfoPBRec &() const { return fInfo; }
|
||||
const struct HFileInfo & FileInfo() const{ return fInfo.hFileInfo; }
|
||||
const struct DirInfo & DirInfo() const { return fInfo.dirInfo; }
|
||||
const struct FInfo & FInfo() const { return fInfo.hFileInfo.ioFlFndrInfo; }
|
||||
const struct FXInfo & FXInfo() const { return fInfo.hFileInfo.ioFlXFndrInfo; }
|
||||
};
|
||||
// \section{Definition of [[GUSIFileSpec]]}
|
||||
//
|
||||
// A [[GUSIFileSpec]] is a manipulation friendly version of an [[FSSpec]]. Due to
|
||||
// conversion operators, a [[GUSIFileSpec]] can be used whereever a [[const FSSpec]]
|
||||
// is specified. For any long term storage, [[FSSpec]] should be used rather than the
|
||||
// much bulkier [[GUSIFileSpec]].
|
||||
//
|
||||
// <Definition of class [[GUSIFileSpec]]>=
|
||||
class GUSIFileSpec {
|
||||
public:
|
||||
// A [[GUSIFileSpec]] can be constructed in lots of different ways. Most of the
|
||||
// constructors have a final argument [[useAlias]] that, when [[true]], suppresses
|
||||
// resolution of leaf aliases.
|
||||
//
|
||||
// First, two trivial cases: The default constructor and the copy constructor, which
|
||||
// do exactly what you'd expect them to do.
|
||||
//
|
||||
// <Constructors for [[GUSIFileSpec]]>=
|
||||
GUSIFileSpec() {}
|
||||
GUSIFileSpec(const GUSIFileSpec & spec);
|
||||
// The [[FSSpec]] conversion is almost a copy constructor, but by default resolves
|
||||
// leaf aliases.
|
||||
//
|
||||
// <Constructors for [[GUSIFileSpec]]>=
|
||||
GUSIFileSpec(const FSSpec & spec, bool useAlias = false);
|
||||
// A number of convenience constructors let you construct a [[GUSIFileSpec]] from
|
||||
// various components.
|
||||
//
|
||||
// <Constructors for [[GUSIFileSpec]]>=
|
||||
// Construct from volume reference number, directory ID & file name
|
||||
GUSIFileSpec(short vRefNum, long parID, ConstStr31Param name, bool useAlias = false);
|
||||
|
||||
// Construct from working directory & file name
|
||||
GUSIFileSpec(short wd, ConstStr31Param name, bool useAlias = false);
|
||||
|
||||
// Construct from full or relative path
|
||||
GUSIFileSpec(const char * path, bool useAlias = false);
|
||||
|
||||
// Construct from open file reference number
|
||||
explicit GUSIFileSpec(short fRefNum);
|
||||
// Finally, there is a constructor for constructing a [[GUSIFileSpec]] for one of
|
||||
// the folders obtainable with [[FindFolder]].
|
||||
//
|
||||
// <Constructors for [[GUSIFileSpec]]>=
|
||||
GUSIFileSpec(OSType object, short vol = kOnSystemDisk);
|
||||
// All [[GUSIFileSpecs]] have an error variable from which the last error
|
||||
// is available.
|
||||
//
|
||||
// <Error handling in [[GUSIFileSpec]]>=
|
||||
OSErr Error() const;
|
||||
operator void*() const;
|
||||
bool operator!() const;
|
||||
// While earlier versions of GUSI maintained a notion of "current directory" that
|
||||
// was independent of the HFS default directory, there is no such distinction anymore
|
||||
// in GUSI 2. [[SetDefaultDirectory]] sets the default directory to [[vRefNum, dirID]].
|
||||
// [[GetDefaultDirectory]] sets [[vRefNum,dirID]] to the default directory. Neither
|
||||
// routine affects the [[name]]. [[GetVolume]] gets the named or indexed volume.
|
||||
//
|
||||
// <Default directory handling in [[GUSIFileSpec]]>=
|
||||
OSErr SetDefaultDirectory();
|
||||
OSErr GetDefaultDirectory();
|
||||
OSErr GetVolume(short index = -1);
|
||||
// Conversions of [[GUSIFileSpec]] to [[FSSpec]] values and references is, of course,
|
||||
// simple. Pointers are a bit trickier; we define an custom [[operator&]] and two
|
||||
// smart pointer classes. [[operator->]], however, is simpler.
|
||||
//
|
||||
// <Converting a [[GUSIFileSpec]] to a [[FSSpec]]>=
|
||||
operator const FSSpec &() const;
|
||||
|
||||
class pointer {
|
||||
public:
|
||||
pointer(GUSIFileSpec * ptr);
|
||||
operator GUSIFileSpec *() const;
|
||||
operator const FSSpec *() const;
|
||||
private:
|
||||
GUSIFileSpec * ptr;
|
||||
};
|
||||
pointer operator&();
|
||||
|
||||
class const_pointer {
|
||||
public:
|
||||
const_pointer(const GUSIFileSpec * ptr);
|
||||
operator const GUSIFileSpec *() const;
|
||||
operator const FSSpec *() const;
|
||||
private:
|
||||
const GUSIFileSpec * ptr;
|
||||
};
|
||||
const_pointer operator&() const;
|
||||
|
||||
const FSSpec * operator->() const;
|
||||
|
||||
friend class pointer;
|
||||
friend class const_pointer;
|
||||
// Each [[GUSIFileSpec]] has an implicit [[GUSICatInfo]] record associated with it.
|
||||
// [[CatInfo]] calls [[GetCatInfo]] if the record is not already valid and
|
||||
// returns a pointer to the record. [[DirInfo]] replaces the [[GUSIFileSpec]] by
|
||||
// the specification of its parent directory and returns a pointer to information
|
||||
// about the parent. Both calls return a [[nil]] pointer if the object does not exist.
|
||||
// If all you are interested in is whether the object exists, call [[Exists]].
|
||||
//
|
||||
// <Getting the [[GUSICatInfo]] for a [[GUSIFileSpec]]>=
|
||||
const GUSICatInfo * CatInfo(short index);
|
||||
const GUSICatInfo * DirInfo();
|
||||
const GUSICatInfo * CatInfo() const;
|
||||
bool Exists() const;
|
||||
// In many POSIXish contexts, it's necessary to specify path names with C string.
|
||||
// Although this practice is dangerous on a Mac, we of course have to conform to
|
||||
// it. The basic operations are getting a full path and getting a path relative to
|
||||
// a directory (the current directory by default).
|
||||
//
|
||||
// <Getting path names from a [[GUSIFileSpec]]>=
|
||||
char * FullPath() const;
|
||||
char * RelativePath() const;
|
||||
char * RelativePath(const FSSpec & dir) const;
|
||||
// If the path ultimately is going to flow back into a GUSI routine again, it is
|
||||
// possible to simply encode the [[GUSIFileSpec]] in ASCII. This is fast and reliable,
|
||||
// but you should of course not employ it with any non-GUSI destination routine and
|
||||
// should never store such a part across a reboot. The standard [[GUSIFileSpec]]
|
||||
// constructors for paths will accept encoded paths.
|
||||
//
|
||||
// The encoding is defined as:
|
||||
//
|
||||
// \begin{itemize}
|
||||
// \item 1 byte: DC1 (ASCII 0x11)
|
||||
// \item 4 bytes: Volume reference number in zero-padded hex
|
||||
// \item 8 bytes: Directory ID in zero-padded hex
|
||||
// \item n bytes: Partial pathname, starting with ':'
|
||||
// \end{itemize}
|
||||
//
|
||||
// <Getting path names from a [[GUSIFileSpec]]>=
|
||||
char * EncodedPath() const;
|
||||
// Most aliases are resolved implicitly, but occasionally you may want to do
|
||||
// explicit resolution. [[Resolve]] resolves an alias. If [[gently]] is set,
|
||||
// nonexistent target files of aliases don't cause an error to be returned.
|
||||
//
|
||||
// <Alias resolution for a [[GUSIFileSpec]]>=
|
||||
OSErr Resolve(bool gently = true);
|
||||
// [[AliasPath]] returns the path an alias points to without mounting any volumes.
|
||||
//
|
||||
// <Alias resolution for a [[GUSIFileSpec]]>=
|
||||
char * AliasPath() const;
|
||||
// A major feature of the [[GUSIFileSpec]] class is the set of operators for
|
||||
// manipulating a file specification.
|
||||
//
|
||||
// [[operator--]] replaces a file specification with the directory specification of
|
||||
// its parent.
|
||||
//
|
||||
// <Manipulating a [[GUSIFileSpec]]>=
|
||||
GUSIFileSpec & operator--();
|
||||
// [[operator++]] sets the [[dirID]] of a directory specification to the ID of the
|
||||
// directory.
|
||||
//
|
||||
// <Manipulating a [[GUSIFileSpec]]>=
|
||||
GUSIFileSpec & operator++();
|
||||
// The two versions of [[operator+=]], which internally both call [[AddPathComponent]],
|
||||
// replace a directory specification with the specification
|
||||
//
|
||||
// <Manipulating a [[GUSIFileSpec]]>=
|
||||
GUSIFileSpec & AddPathComponent(const char * name, int length, bool fullSpec);
|
||||
GUSIFileSpec & operator+=(ConstStr31Param name);
|
||||
GUSIFileSpec & operator+=(const char * name);
|
||||
// [[operator+]] provides a non-destructive variant of [[operator+=]].
|
||||
//
|
||||
// <Manipulating a [[GUSIFileSpec]]>=
|
||||
//
|
||||
// These don't need access to the GUSIFileSpec internals
|
||||
//
|
||||
// friend GUSIFileSpec operator+(const FSSpec & spec, ConstStr31Param name);
|
||||
// friend GUSIFileSpec operator+(const FSSpec & spec, const char * name);
|
||||
// Array access replaces the file specification with the [[index]]th object in the
|
||||
// {\em parent directory} of the specification (allowing the same specification to
|
||||
// be reused for reading a directory).
|
||||
//
|
||||
// <Manipulating a [[GUSIFileSpec]]>=
|
||||
GUSIFileSpec & operator[](short index);
|
||||
// To manipulate the fields of the file specification directly, there is a procedural
|
||||
// interface.
|
||||
//
|
||||
// <Manipulating a [[GUSIFileSpec]]>=
|
||||
void SetVRef(short vref);
|
||||
void SetParID(long parid);
|
||||
void SetName(ConstStr63Param nam);
|
||||
void SetName(const char * nam);
|
||||
// For some modifications to propagate quickly, the surrounding folder needs to
|
||||
// have its date modified.
|
||||
//
|
||||
// <Manipulating a [[GUSIFileSpec]]>=
|
||||
OSErr TouchFolder();
|
||||
// Two [[GUSIFileSpecs]] can be compared for (in)equality.
|
||||
//
|
||||
// <Comparing two [[GUSIFileSpec]] objects>=
|
||||
friend bool operator==(const GUSIFileSpec & one, const GUSIFileSpec & other);
|
||||
// [[IsParentOf]] determines whether the object specifies a parent directory of
|
||||
// [[other]].
|
||||
//
|
||||
// <Comparing two [[GUSIFileSpec]] objects>=
|
||||
bool IsParentOf(const GUSIFileSpec & other) const;
|
||||
protected:
|
||||
// \section{Implementation of [[GUSIFileSpec]]}
|
||||
//
|
||||
// [[sError]] contains the error code for failed calls. [[Error]] returns the value.
|
||||
//
|
||||
// <Privatissima of [[GUSIFileSpec]]>=
|
||||
mutable OSErr fError;
|
||||
// For path name constructions, a sometimes large scratch area is needed which is
|
||||
// maintained in [[sScratch]]. A scratch request preserves a preexisting scratch area
|
||||
// at the {\em end} of the new area if [[extend]] is nonzero.
|
||||
//
|
||||
// <Privatissima of [[GUSIFileSpec]]>=
|
||||
static char * sScratch;
|
||||
static long sScratchSize;
|
||||
|
||||
static char * CScratch(bool extend = false);
|
||||
static StringPtr PScratch();
|
||||
// A [[GUSIFileSpec]] has a [[GUSICatInfo]] embedded and a flag [[fValidInfo]] indicating
|
||||
// that it is valid.
|
||||
//
|
||||
// <Privatissima of [[GUSIFileSpec]]>=
|
||||
FSSpec fSpec;
|
||||
GUSIIOPBWrapper<GUSICatInfo> fInfo;
|
||||
bool fValidInfo;
|
||||
// For convenience, we define a fictivous parent directory of all volumes.
|
||||
//
|
||||
// <Privatissima of [[GUSIFileSpec]]>=
|
||||
enum { ROOT_MAGIC_COOKIE = 666 };
|
||||
// Each accumulation step is preformed in [[PrependPathComponent]].
|
||||
//
|
||||
// <Privatissima of [[GUSIFileSpec]]>=
|
||||
OSErr PrependPathComponent(char *&path, ConstStr63Param component, bool colon) const;
|
||||
};
|
||||
// A [[GUSITempFileSpec]] is just a [[GUSIFileSpec]] with constructors to construct
|
||||
// filenames for temporary files.
|
||||
//
|
||||
// <Definition of class [[GUSIFileSpec]]>=
|
||||
class GUSITempFileSpec : public GUSIFileSpec {
|
||||
public:
|
||||
GUSITempFileSpec(short vRefNum = kOnSystemDisk);
|
||||
GUSITempFileSpec(short vRefNum, long parID);
|
||||
GUSITempFileSpec(ConstStr31Param basename);
|
||||
GUSITempFileSpec(short vRefNum, ConstStr31Param basename);
|
||||
GUSITempFileSpec(short vRefNum, long parID, ConstStr31Param basename);
|
||||
private:
|
||||
void TempName();
|
||||
void TempName(ConstStr31Param basename);
|
||||
|
||||
static int sID;
|
||||
};
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=reset
|
||||
#endif
|
||||
|
||||
// \section{Implementation of [[GUSICatInfo]]}
|
||||
//
|
||||
// All of the member functions for [[GUSICatInfo]] are inline.
|
||||
//
|
||||
// <Inline member functions for class [[GUSICatInfo]]>=
|
||||
inline bool GUSICatInfo::IsFile() const
|
||||
{
|
||||
return !(DirInfo().ioFlAttrib & 0x10);
|
||||
}
|
||||
|
||||
inline bool GUSICatInfo::IsAlias() const
|
||||
{
|
||||
return
|
||||
!(FileInfo().ioFlAttrib & 0x10) &&
|
||||
(FInfo().fdFlags & (1 << 15));
|
||||
}
|
||||
|
||||
inline bool GUSICatInfo::DirIsExported() const
|
||||
{
|
||||
return (FileInfo().ioFlAttrib & 0x20) != 0;
|
||||
}
|
||||
|
||||
inline bool GUSICatInfo::DirIsMounted() const
|
||||
{
|
||||
return (FileInfo().ioFlAttrib & 0x08) != 0;
|
||||
}
|
||||
|
||||
inline bool GUSICatInfo::DirIsShared() const
|
||||
{
|
||||
return (FileInfo().ioFlAttrib & 0x04) != 0;
|
||||
}
|
||||
|
||||
inline bool GUSICatInfo::HasRdPerm() const
|
||||
{
|
||||
return !(DirInfo().ioACUser & 0x02) != 0;
|
||||
}
|
||||
|
||||
inline bool GUSICatInfo::HasWrPerm() const
|
||||
{
|
||||
return !(DirInfo().ioACUser & 0x04) != 0;
|
||||
}
|
||||
|
||||
inline bool GUSICatInfo::Locked() const
|
||||
{
|
||||
return (FileInfo().ioFlAttrib & 0x11) == 0x01;
|
||||
}
|
||||
// <Inline member functions for class [[GUSIFileSpec]]>=
|
||||
inline OSErr GUSIFileSpec::Error() const
|
||||
{
|
||||
return fError;
|
||||
}
|
||||
|
||||
inline GUSIFileSpec::operator void*() const
|
||||
{
|
||||
return (void *)!fError;
|
||||
}
|
||||
|
||||
inline bool GUSIFileSpec::operator!() const
|
||||
{
|
||||
return fError!=0;
|
||||
}
|
||||
// <Inline member functions for class [[GUSIFileSpec]]>=
|
||||
inline StringPtr GUSIFileSpec::PScratch()
|
||||
{
|
||||
return (StringPtr) CScratch();
|
||||
}
|
||||
// <Inline member functions for class [[GUSIFileSpec]]>=
|
||||
inline OSErr GUSIFileSpec::SetDefaultDirectory()
|
||||
{
|
||||
return fError = HSetVol(nil, fSpec.vRefNum, fSpec.parID);
|
||||
}
|
||||
|
||||
inline OSErr GUSIFileSpec::GetDefaultDirectory()
|
||||
{
|
||||
fSpec.name[0] = 0;
|
||||
fValidInfo = false;
|
||||
return fError = HGetVol(nil, &fSpec.vRefNum, &fSpec.parID);
|
||||
}
|
||||
// [[operator+=]] and [[operator+]] are merely wrappers around [[AddPathComponent]].
|
||||
//
|
||||
// <Inline member functions for class [[GUSIFileSpec]]>=
|
||||
inline GUSIFileSpec & GUSIFileSpec::operator+=(ConstStr31Param name)
|
||||
{
|
||||
return AddPathComponent((char *) name+1, name[0], true);
|
||||
}
|
||||
|
||||
inline GUSIFileSpec & GUSIFileSpec::operator+=(const char * name)
|
||||
{
|
||||
return AddPathComponent(name, strlen(name), true);
|
||||
}
|
||||
// The other variations of the call are simple.
|
||||
//
|
||||
// <Inline member functions for class [[GUSIFileSpec]]>=
|
||||
inline const GUSICatInfo * GUSIFileSpec::CatInfo() const
|
||||
{
|
||||
return const_cast<GUSIFileSpec *>(this)->CatInfo(0);
|
||||
}
|
||||
|
||||
inline const GUSICatInfo * GUSIFileSpec::DirInfo()
|
||||
{
|
||||
if (CatInfo(-1)) {
|
||||
fSpec.parID = fInfo->DirInfo().ioDrParID;
|
||||
fValidInfo = true;
|
||||
|
||||
return &fInfo.fPB;
|
||||
} else
|
||||
return nil;
|
||||
}
|
||||
|
||||
inline bool GUSIFileSpec::Exists() const
|
||||
{
|
||||
return CatInfo() != nil;
|
||||
}
|
||||
// Reference conversion is straightforward, as is [[operator->]].
|
||||
//
|
||||
// <Inline member functions for class [[GUSIFileSpec]]>=
|
||||
inline GUSIFileSpec::operator const FSSpec &() const
|
||||
{
|
||||
return fSpec;
|
||||
}
|
||||
inline const FSSpec * GUSIFileSpec::operator->() const
|
||||
{
|
||||
return &fSpec;
|
||||
}
|
||||
// Pointers, however, are a trickier issue, as they might be used either as a
|
||||
// [[GUSIFileSpec *]] or as an [[FSSpec *]].
|
||||
//
|
||||
// <Inline member functions for class [[GUSIFileSpec]]>=
|
||||
inline GUSIFileSpec::const_pointer::const_pointer(const GUSIFileSpec * ptr)
|
||||
: ptr(ptr)
|
||||
{
|
||||
}
|
||||
inline GUSIFileSpec::const_pointer::operator const GUSIFileSpec *() const
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
inline GUSIFileSpec::const_pointer::operator const FSSpec *() const
|
||||
{
|
||||
return &ptr->fSpec;
|
||||
}
|
||||
inline GUSIFileSpec::const_pointer GUSIFileSpec::operator&() const
|
||||
{
|
||||
return const_pointer(this);
|
||||
}
|
||||
// [[GUSIFileSpec::pointer]] is the non-constant equivalent to [[GUSIFileSpec::const_pointer]].
|
||||
//
|
||||
// <Inline member functions for class [[GUSIFileSpec]]>=
|
||||
inline GUSIFileSpec::pointer::pointer(GUSIFileSpec * ptr)
|
||||
: ptr(ptr)
|
||||
{
|
||||
}
|
||||
inline GUSIFileSpec::pointer::operator GUSIFileSpec *() const
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
inline GUSIFileSpec::pointer::operator const FSSpec *() const
|
||||
{
|
||||
return &ptr->fSpec;
|
||||
}
|
||||
inline GUSIFileSpec::pointer GUSIFileSpec::operator&()
|
||||
{
|
||||
return pointer(this);
|
||||
}
|
||||
|
||||
#endif /* GUSI_SOURCE */
|
||||
|
||||
#endif /* GUSIFileSpec */
|
|
@ -1,52 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSIForeignThreads.nw - Foreign thread support
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:11 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.4 2000/12/23 06:10:48 neeri
|
||||
// % Use kPowerPCCFragArch, NOT GetCurrentArchitecture()
|
||||
// %
|
||||
// % Revision 1.3 2000/05/23 07:00:00 neeri
|
||||
// % Improve formatting
|
||||
// %
|
||||
// % Revision 1.2 2000/03/06 08:28:32 neeri
|
||||
// % Releasing 2.0.5
|
||||
// %
|
||||
// % Revision 1.1 1999/09/09 07:18:06 neeri
|
||||
// % Added support for foreign threads
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{Supporting threads made outside of GUSI}
|
||||
//
|
||||
// As convenient as the pthreads interface is, some applications may link to other
|
||||
// libraries which create thread manager threads directly, such as the PowerPlant
|
||||
// thread classes.
|
||||
//
|
||||
// Unfortunately, there is no really elegant way to welcome these lost sheep into the
|
||||
// pthread flock, since the thread manager offers no way to retrieve thread switching
|
||||
// and termination procedures. We therefore have to resort to a violent technique used
|
||||
// already successfully for MPW support: On CFM, we override the default entry point and
|
||||
// use the CFM manager to find the real implementation.
|
||||
//
|
||||
// For non-CFM, we unfortunately don't have such an effective technique, since the
|
||||
// thread manager is called through traps (and no, I'm not going to patch any traps
|
||||
// for this). You will therefore have to recompile your foreign libraries with
|
||||
// a precompiled header that includes \texttt{GUSIForeignThreads.h}.
|
||||
//
|
||||
// <GUSIForeignThreads.h>=
|
||||
#ifndef _GUSIForeignThreads_
|
||||
#define _GUSIForeignThreads_
|
||||
|
||||
#define NewThread(style, entry, param, stack, options, result, made) \
|
||||
GUSINewThread((style), (entry), (param), (stack), (options), (result), (made))
|
||||
#define SetThreadSwitcher(thread, switcher, param, inOrOut) \
|
||||
GUSISetThreadSwitcher((thread), (switcher), (param), (inOrOut))
|
||||
#define SetThreadTerminator(thread, threadTerminator, terminationProcParam) \
|
||||
GUSISetThreadTerminator((thread), (threadTerminator), (terminationProcParam))
|
||||
#endif /* _GUSIForeignThreads_ */
|
|
@ -1,68 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSIMTInet.nw - Common routines for MacTCP
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:11 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.5 1999/08/26 05:45:02 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.4 1999/05/29 06:26:43 neeri
|
||||
// % Fixed header guards
|
||||
// %
|
||||
// % Revision 1.3 1998/11/22 23:06:53 neeri
|
||||
// % Releasing 2.0a4 in a hurry
|
||||
// %
|
||||
// % Revision 1.2 1998/10/25 11:57:34 neeri
|
||||
// % Ready to release 2.0a3
|
||||
// %
|
||||
// % Revision 1.1 1998/08/01 21:32:05 neeri
|
||||
// % About ready for 2.0a1
|
||||
// %
|
||||
// % Revision 1.4 1998/02/11 12:57:12 neeri
|
||||
// % PowerPC Build
|
||||
// %
|
||||
// % Revision 1.3 1998/01/25 20:53:55 neeri
|
||||
// % Engine implemented, except for signals & scheduling
|
||||
// %
|
||||
// % Revision 1.2 1996/12/22 19:57:56 neeri
|
||||
// % TCP streams work
|
||||
// %
|
||||
// % Revision 1.1 1996/12/16 02:12:40 neeri
|
||||
// % TCP Sockets sort of work
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{TCP/IP shared infrastructure}
|
||||
//
|
||||
// Both the MacTCP and the forthcoming open transport implementation of TCP/IP
|
||||
// sockets share a common registry.
|
||||
//
|
||||
// <GUSIInet.h>=
|
||||
#ifndef _GUSIInet_
|
||||
#define _GUSIInet_
|
||||
|
||||
#ifdef GUSI_SOURCE
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
// <Definition of [[GUSIwithInetSockets]]>=
|
||||
void GUSIwithInetSockets();
|
||||
__END_DECLS
|
||||
|
||||
#ifdef GUSI_INTERNAL
|
||||
|
||||
#include "GUSIFactory.h"
|
||||
|
||||
extern GUSISocketTypeRegistry gGUSIInetFactories;
|
||||
|
||||
#endif /* GUSI_INTERNAL */
|
||||
|
||||
#endif /* GUSI_SOURCE */
|
||||
|
||||
#endif /* _GUSIInet_ */
|
|
@ -1,104 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSIBasics.nw - Common routines for GUSI
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.20 2001/01/17 08:32:30 neeri
|
||||
// % Atomic locks turned out not to be necessary after all
|
||||
// %
|
||||
// % Revision 1.19 2001/01/17 08:31:10 neeri
|
||||
// % Added PPC error codes, tweaked nullEvent handling, added atomic locks
|
||||
// %
|
||||
// % Revision 1.18 2000/10/16 04:34:22 neeri
|
||||
// % Releasing 2.1.2
|
||||
// %
|
||||
// % Revision 1.17 2000/06/12 04:20:58 neeri
|
||||
// % Introduce GUSI_*printf
|
||||
// %
|
||||
// % Revision 1.16 2000/05/23 06:51:55 neeri
|
||||
// % Reorganize errors to improve formatting
|
||||
// %
|
||||
// % Revision 1.15 2000/03/15 07:22:05 neeri
|
||||
// % Enforce alignment choices
|
||||
// %
|
||||
// % Revision 1.14 1999/08/26 05:44:58 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.13 1999/08/02 07:02:42 neeri
|
||||
// % Support for asynchronous errors and other socket options
|
||||
// %
|
||||
// % Revision 1.12 1999/06/28 05:56:01 neeri
|
||||
// % Get rid of STL includes in header
|
||||
// %
|
||||
// % Revision 1.11 1999/06/08 04:31:29 neeri
|
||||
// % Getting ready for 2.0b2
|
||||
// %
|
||||
// % Revision 1.10 1999/05/30 03:09:28 neeri
|
||||
// % Added support for MPW compilers
|
||||
// %
|
||||
// % Revision 1.9 1999/04/10 04:45:05 neeri
|
||||
// % Handle MacTCP errors correctly
|
||||
// %
|
||||
// % Revision 1.8 1999/03/17 09:05:04 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// % Revision 1.7 1998/10/25 11:57:33 neeri
|
||||
// % Ready to release 2.0a3
|
||||
// %
|
||||
// % Revision 1.6 1998/10/11 16:45:09 neeri
|
||||
// % Ready to release 2.0a2
|
||||
// %
|
||||
// % Revision 1.5 1998/01/25 20:53:50 neeri
|
||||
// % Engine implemented, except for signals & scheduling
|
||||
// %
|
||||
// % Revision 1.4 1996/12/22 19:57:54 neeri
|
||||
// % TCP streams work
|
||||
// %
|
||||
// % Revision 1.3 1996/11/24 12:52:04 neeri
|
||||
// % Added GUSIPipeSockets
|
||||
// %
|
||||
// % Revision 1.2 1996/11/18 00:53:46 neeri
|
||||
// % TestTimers (basic threading/timer test) works
|
||||
// %
|
||||
// % Revision 1.1.1.1 1996/11/03 02:43:32 neeri
|
||||
// % Imported into CVS
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{Common routines for GUSI}
|
||||
//
|
||||
// This section defines various services used by all parts of GUSI:
|
||||
//
|
||||
// \begin{itemize}
|
||||
// \item Various hooks to customize GUSI.
|
||||
// \item The propagation of {\bf errors} to the [[errno]] and [[h_errno]]
|
||||
// global variables.
|
||||
// \item Waiting for completion of asynchronous calls.
|
||||
// \item Event handling.
|
||||
// \item Compiler features.
|
||||
// \end{itemize}
|
||||
//
|
||||
// To protect our name space further, we maintain a strict C interface unless
|
||||
// [[GUSI_SOURCE]] is defined, and may avoid defining some stuff unless
|
||||
// [[GUSI_INTERNAL]] is defined. The following header is therefore included
|
||||
// first by all GUSI source files.
|
||||
//
|
||||
// <GUSIInternal.h>=
|
||||
#ifndef _GUSIInternal_
|
||||
#define _GUSIInternal_
|
||||
|
||||
#include <ConditionalMacros.h>
|
||||
|
||||
#define GUSI_SOURCE
|
||||
#define GUSI_INTERNAL
|
||||
|
||||
#if !TARGET_RT_MAC_CFM
|
||||
#pragma segment GUSI
|
||||
#endif
|
||||
|
||||
#endif /* _GUSIInternal_ */
|
|
@ -1,65 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSIMPW.nw - MPW Interface
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.13 2001/01/17 08:48:04 neeri
|
||||
// % Introduce Expired(), Reset()
|
||||
// %
|
||||
// % Revision 1.12 2000/05/23 07:01:53 neeri
|
||||
// % Improve formatting
|
||||
// %
|
||||
// % Revision 1.11 1999/08/26 05:45:03 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.10 1999/07/19 06:17:08 neeri
|
||||
// % Add SIOW support
|
||||
// %
|
||||
// % Revision 1.9 1999/07/07 04:17:41 neeri
|
||||
// % Final tweaks for 2.0b3
|
||||
// %
|
||||
// % Revision 1.8 1999/06/08 04:31:29 neeri
|
||||
// % Getting ready for 2.0b2
|
||||
// %
|
||||
// % Revision 1.7 1999/05/29 06:26:43 neeri
|
||||
// % Fixed header guards
|
||||
// %
|
||||
// % Revision 1.6 1999/04/29 05:33:20 neeri
|
||||
// % Fix fcntl prototype
|
||||
// %
|
||||
// % Revision 1.5 1999/03/29 09:51:28 neeri
|
||||
// % New configuration system with support for hardcoded configurations.
|
||||
// %
|
||||
// % Revision 1.4 1999/03/17 09:05:08 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// % Revision 1.3 1998/11/22 23:06:54 neeri
|
||||
// % Releasing 2.0a4 in a hurry
|
||||
// %
|
||||
// % Revision 1.2 1998/10/25 11:57:35 neeri
|
||||
// % Ready to release 2.0a3
|
||||
// %
|
||||
// % Revision 1.1 1998/08/01 21:32:06 neeri
|
||||
// % About ready for 2.0a1
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{MPW Support}
|
||||
//
|
||||
// In MPW tools, we have to direct some of the I/O operations to the standard
|
||||
// library functions, which we otherwise try to avoid as much as possible.
|
||||
// Getting at those library calls is a bit tricky: For 68K, we rename entries
|
||||
// in the MPW glue library, while for PowerPC, we look up the symbols dynamically.
|
||||
//
|
||||
// MPW support is installed implicitly through [[GUSISetupConsoleDescriptors]]
|
||||
//
|
||||
// <GUSIMPW.h>=
|
||||
#ifndef _GUSIMPW_
|
||||
#define _GUSIMPW_
|
||||
|
||||
#endif /* _GUSIMPW_ */
|
|
@ -1,56 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSIMSL.nw - Interface to the MSL
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.8 2000/10/29 19:17:04 neeri
|
||||
// % Accommodate MSL's non-compliant fopen signature
|
||||
// %
|
||||
// % Revision 1.7 2000/10/16 04:34:22 neeri
|
||||
// % Releasing 2.1.2
|
||||
// %
|
||||
// % Revision 1.6 2000/05/23 07:03:25 neeri
|
||||
// % Improve formatting
|
||||
// %
|
||||
// % Revision 1.5 1999/08/26 05:45:03 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.4 1999/08/02 07:02:43 neeri
|
||||
// % Support for asynchronous errors and other socket options
|
||||
// %
|
||||
// % Revision 1.3 1999/04/14 04:20:21 neeri
|
||||
// % Override console hooks
|
||||
// %
|
||||
// % Revision 1.2 1999/04/10 04:53:58 neeri
|
||||
// % Use simpler internal MSL routines
|
||||
// %
|
||||
// % Revision 1.1 1998/08/01 21:32:07 neeri
|
||||
// % About ready for 2.0a1
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{The Interface to the MSL}
|
||||
//
|
||||
// This section interfaces GUSI to the Metrowerks Standard Library (MSL)
|
||||
// by reimplementing various internal MSL routines. Consequently, some of
|
||||
// the code used here is borrowed from the MSL code itself. The routines
|
||||
// here are in three different categories:
|
||||
//
|
||||
// \begin{itemize}
|
||||
// \item Overrides of MSL functions (all internal, as it happens).
|
||||
// \item Implementations of ANSI library specific public GUSI functions like
|
||||
// [[fdopen]].
|
||||
// \item Implementations of ANSI library specific internal GUSI functions.
|
||||
// \end{itemize}
|
||||
//
|
||||
//
|
||||
// <GUSIMSL.h>=
|
||||
#ifndef _GUSIMSL_
|
||||
#define _GUSIMSL_
|
||||
|
||||
#endif /* _GUSIMSL_ */
|
|
@ -1,194 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSIMTInet.nw - Common routines for MacTCP
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.14 2000/10/16 04:34:23 neeri
|
||||
// % Releasing 2.1.2
|
||||
// %
|
||||
// % Revision 1.13 2000/05/23 07:03:25 neeri
|
||||
// % Improve formatting
|
||||
// %
|
||||
// % Revision 1.12 1999/08/26 05:45:04 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.11 1999/08/02 07:02:43 neeri
|
||||
// % Support for asynchronous errors and other socket options
|
||||
// %
|
||||
// % Revision 1.10 1999/06/30 07:42:06 neeri
|
||||
// % Getting ready to release 2.0b3
|
||||
// %
|
||||
// % Revision 1.9 1999/05/29 06:26:43 neeri
|
||||
// % Fixed header guards
|
||||
// %
|
||||
// % Revision 1.8 1999/04/29 05:33:19 neeri
|
||||
// % Fix fcntl prototype
|
||||
// %
|
||||
// % Revision 1.7 1999/03/17 09:05:08 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// % Revision 1.6 1998/10/25 11:57:35 neeri
|
||||
// % Ready to release 2.0a3
|
||||
// %
|
||||
// % Revision 1.5 1998/10/11 16:45:16 neeri
|
||||
// % Ready to release 2.0a2
|
||||
// %
|
||||
// % Revision 1.4 1998/02/11 12:57:12 neeri
|
||||
// % PowerPC Build
|
||||
// %
|
||||
// % Revision 1.3 1998/01/25 20:53:55 neeri
|
||||
// % Engine implemented, except for signals & scheduling
|
||||
// %
|
||||
// % Revision 1.2 1996/12/22 19:57:56 neeri
|
||||
// % TCP streams work
|
||||
// %
|
||||
// % Revision 1.1 1996/12/16 02:12:40 neeri
|
||||
// % TCP Sockets sort of work
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{Basic MacTCP code}
|
||||
//
|
||||
// A [[GUSIMTInetSocket]] defines the infrastructure shared between
|
||||
// MacTCP TCP and UDP sockets.
|
||||
//
|
||||
// <GUSIMTInet.h>=
|
||||
#ifndef _GUSIMTInet_
|
||||
#define _GUSIMTInet_
|
||||
|
||||
#ifdef GUSI_SOURCE
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
// <Definition of [[GUSIwithMTInetSockets]]>=
|
||||
void GUSIwithMTInetSockets();
|
||||
__END_DECLS
|
||||
|
||||
#ifdef GUSI_INTERNAL
|
||||
|
||||
#include "GUSISocket.h"
|
||||
#include "GUSISocketMixins.h"
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <MacTCP.h>
|
||||
|
||||
// \section{Definition of [[GUSIMTInetSocket]]}
|
||||
//
|
||||
// MacTCP related sockets are buffered, have a standard state model, and can be
|
||||
// nonblocking.
|
||||
//
|
||||
// <Definition of class [[GUSIMTInetSocket]]>=
|
||||
class GUSIMTInetSocket :
|
||||
public GUSISocket,
|
||||
protected GUSISMBlocking,
|
||||
protected GUSISMState,
|
||||
protected GUSISMInputBuffer,
|
||||
protected GUSISMOutputBuffer,
|
||||
protected GUSISMAsyncError
|
||||
{
|
||||
public:
|
||||
GUSIMTInetSocket();
|
||||
// [[bind]] for MacTCP sockets has the fatal flaw that it is totally unable to
|
||||
// reserve a socket.
|
||||
//
|
||||
// <Overridden member functions for [[GUSIMTInetSocket]]>=
|
||||
virtual int bind(void * addr, socklen_t namelen);
|
||||
// [[getsockname]] and [[getpeername]] return the stored values.
|
||||
//
|
||||
// <Overridden member functions for [[GUSIMTInetSocket]]>=
|
||||
virtual int getsockname(void * addr, socklen_t * namelen);
|
||||
virtual int getpeername(void * addr, socklen_t * namelen);
|
||||
// [[shutdown]] just delegates to [[GUSISMState]].
|
||||
//
|
||||
// <Overridden member functions for [[GUSIMTInetSocket]]>=
|
||||
virtual int shutdown(int how);
|
||||
// [[fcntl]] handles the blocking support.
|
||||
//
|
||||
// <Overridden member functions for [[GUSIMTInetSocket]]>=
|
||||
virtual int fcntl(int cmd, va_list arg);
|
||||
// [[ioctl]] deals with blocking support and with [[FIONREAD]].
|
||||
//
|
||||
// <Overridden member functions for [[GUSIMTInetSocket]]>=
|
||||
virtual int ioctl(unsigned int request, va_list arg);
|
||||
// [[getsockopt]] and [[setsockopt]] are available for setting buffer sizes and
|
||||
// getting asynchronous errors.
|
||||
//
|
||||
// <Overridden member functions for [[GUSIMTInetSocket]]>=
|
||||
virtual int getsockopt(int level, int optname, void *optval, socklen_t * optlen);
|
||||
// <Overridden member functions for [[GUSIMTInetSocket]]>=
|
||||
virtual int setsockopt(int level, int optname, void *optval, socklen_t optlen);
|
||||
// MacTCP sockets implement socket style calls.
|
||||
//
|
||||
// <Overridden member functions for [[GUSIMTInetSocket]]>=
|
||||
virtual bool Supports(ConfigOption config);
|
||||
// MacTCP I/O calls communicate by means of read and write data structures,
|
||||
// of which we need only the most primitive variants.
|
||||
//
|
||||
// <Definition of classes [[MiniWDS]] and [[MidiWDS]]>=
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=mac68k
|
||||
#endif
|
||||
class MiniWDS {
|
||||
public:
|
||||
u_short fLength;
|
||||
char * fDataPtr;
|
||||
u_short fZero;
|
||||
|
||||
MiniWDS() : fZero(0) {}
|
||||
Ptr operator &() { return (Ptr)this; }
|
||||
};
|
||||
class MidiWDS {
|
||||
public:
|
||||
u_short fLength;
|
||||
char * fDataPtr;
|
||||
u_short fLength2;
|
||||
char * fDataPtr2;
|
||||
u_short fZero;
|
||||
|
||||
MidiWDS() : fZero(0) {}
|
||||
Ptr operator &() { return (Ptr)this; }
|
||||
};
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=reset
|
||||
#endif
|
||||
// The only other interesting bit in the interface is the driver management, which
|
||||
// arranges to open the MacTCP driver and domain name resolver at most once,
|
||||
// as late as possible in the program (If you open some SLIP or PPP drivers
|
||||
// before the Toolbox is initialized, you'll wish you'd curled up by the fireside
|
||||
// with a nice Lovecraft novel instead). [[Driver]] returns the driver reference
|
||||
// number of the MacTCP driver. [[HostAddr]] returns our host's IP address.
|
||||
//
|
||||
// <MacTCP driver management>=
|
||||
static short Driver();
|
||||
static u_long HostAddr();
|
||||
protected:
|
||||
// All MacTCP related sockets need a [[StreamPtr]]; they store their own and
|
||||
// their peer's address away, and the save errors reported at interrupt time
|
||||
// in an [[fAsyncError]] field.
|
||||
//
|
||||
// <Data members for [[GUSIMTInetSocket]]>=
|
||||
StreamPtr fStream;
|
||||
sockaddr_in fSockAddr;
|
||||
sockaddr_in fPeerAddr;
|
||||
// \section{Implementation of [[GUSIMTInetSocket]]}
|
||||
//
|
||||
// [[Driver]] preserves error status in an [[OSErr]]
|
||||
// variable, initially [[1]] to convey unresolvedness.
|
||||
//
|
||||
// <Data members for [[GUSIMTInetSocket]]>=
|
||||
static short sDrvrRefNum;
|
||||
static OSErr sDrvrState;
|
||||
static u_long sHostAddress;
|
||||
};
|
||||
|
||||
#endif /* GUSI_INTERNAL */
|
||||
|
||||
#endif /* GUSI_SOURCE */
|
||||
|
||||
#endif /* _GUSIMTInet_ */
|
|
@ -1,69 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSINetDB.nw - Convert between names and adresses
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.7 2000/06/12 04:20:59 neeri
|
||||
// % Introduce GUSI_*printf
|
||||
// %
|
||||
// % Revision 1.6 2000/03/06 06:10:02 neeri
|
||||
// % Reorganize Yield()
|
||||
// %
|
||||
// % Revision 1.5 1999/08/26 05:45:04 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.4 1999/05/30 03:09:30 neeri
|
||||
// % Added support for MPW compilers
|
||||
// %
|
||||
// % Revision 1.3 1999/03/17 09:05:08 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// % Revision 1.2 1998/10/25 11:57:36 neeri
|
||||
// % Ready to release 2.0a3
|
||||
// %
|
||||
// % Revision 1.1 1998/10/11 16:45:17 neeri
|
||||
// % Ready to release 2.0a2
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{IP Name Lookup in MacTCP}
|
||||
//
|
||||
//
|
||||
// <GUSIMTNetDB.h>=
|
||||
#ifndef _GUSIMTNetDB_
|
||||
#define _GUSIMTNetDB_
|
||||
|
||||
#ifdef GUSI_INTERNAL
|
||||
#include "GUSINetDB.h"
|
||||
|
||||
// \section{Definition of [[GUSIMTNetDB]]}
|
||||
//
|
||||
//
|
||||
// <Definition of class [[GUSIMTNetDB]]>=
|
||||
class GUSIMTNetDB : public GUSINetDB {
|
||||
public:
|
||||
static void Instantiate();
|
||||
static bool Resolver();
|
||||
|
||||
// <Overridden member functions for [[GUSIMTNetDB]]>=
|
||||
virtual hostent * gethostbyname(const char * name);
|
||||
// <Overridden member functions for [[GUSIMTNetDB]]>=
|
||||
virtual hostent * gethostbyaddr(const void * addr, size_t len, int type);
|
||||
// <Overridden member functions for [[GUSIMTNetDB]]>=
|
||||
virtual char * inet_ntoa(in_addr inaddr);
|
||||
// <Overridden member functions for [[GUSIMTNetDB]]>=
|
||||
virtual long gethostid();
|
||||
private:
|
||||
GUSIMTNetDB() {}
|
||||
GUSISpecificData<GUSIhostent,GUSIKillHostEnt> fHost;
|
||||
static OSErr sResolverState;
|
||||
};
|
||||
|
||||
#endif /* GUSI_INTERNAL */
|
||||
|
||||
#endif /* _GUSIMTNetDB_ */
|
|
@ -1,113 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSIMTTcp.nw - TCP code for MacTCP
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.17 2000/10/16 04:01:59 neeri
|
||||
// % Save A5 in completion routines
|
||||
// %
|
||||
// % Revision 1.16 2000/05/23 07:04:20 neeri
|
||||
// % Improve formatting, fix hang on close
|
||||
// %
|
||||
// % Revision 1.15 2000/03/06 06:10:02 neeri
|
||||
// % Reorganize Yield()
|
||||
// %
|
||||
// % Revision 1.14 1999/08/26 05:42:13 neeri
|
||||
// % Fix nonblocking connects
|
||||
// %
|
||||
// % Revision 1.13 1999/08/02 07:02:44 neeri
|
||||
// % Support for asynchronous errors and other socket options
|
||||
// %
|
||||
// % Revision 1.12 1999/06/28 06:04:58 neeri
|
||||
// % Support interrupted calls
|
||||
// %
|
||||
// % Revision 1.11 1999/06/08 04:31:29 neeri
|
||||
// % Getting ready for 2.0b2
|
||||
// %
|
||||
// % Revision 1.10 1999/05/30 03:09:30 neeri
|
||||
// % Added support for MPW compilers
|
||||
// %
|
||||
// % Revision 1.9 1999/03/17 09:05:08 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// % Revision 1.8 1998/11/22 23:06:55 neeri
|
||||
// % Releasing 2.0a4 in a hurry
|
||||
// %
|
||||
// % Revision 1.7 1998/10/25 11:31:42 neeri
|
||||
// % Add MSG_PEEK support, make releases more orderly.
|
||||
// %
|
||||
// % Revision 1.6 1998/10/11 16:45:18 neeri
|
||||
// % Ready to release 2.0a2
|
||||
// %
|
||||
// % Revision 1.5 1998/08/01 21:32:07 neeri
|
||||
// % About ready for 2.0a1
|
||||
// %
|
||||
// % Revision 1.4 1998/01/25 20:53:56 neeri
|
||||
// % Engine implemented, except for signals & scheduling
|
||||
// %
|
||||
// % Revision 1.3 1997/11/13 21:12:11 neeri
|
||||
// % Fall 1997
|
||||
// %
|
||||
// % Revision 1.2 1996/12/22 19:57:57 neeri
|
||||
// % TCP streams work
|
||||
// %
|
||||
// % Revision 1.1 1996/12/16 02:12:41 neeri
|
||||
// % TCP Sockets sort of work
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{MacTCP TCP sockets}
|
||||
//
|
||||
// A [[GUSIMTTcpSocket]] implements the TCP socket class for MacTCP. All instances
|
||||
// of [[GUSIMTTcpSocket]] are created by the [[GUSIMTTcpFactory]] singleton, so
|
||||
// there is no point in exporting the class itself.
|
||||
//
|
||||
// <GUSIMTTcp.h>=
|
||||
#ifndef _GUSIMTTcp_
|
||||
#define _GUSIMTTcp_
|
||||
|
||||
#ifdef GUSI_SOURCE
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
// \section{Definition of [[GUSIMTTcpFactory]]}
|
||||
//
|
||||
// [[GUSIMTTcpFactory]] is a singleton subclass of [[GUSISocketFactory]].
|
||||
//
|
||||
// <Definition of [[GUSIwithMTTcpSockets]]>=
|
||||
void GUSIwithMTTcpSockets();
|
||||
__END_DECLS
|
||||
|
||||
#ifdef GUSI_INTERNAL
|
||||
|
||||
#include "GUSIFactory.h"
|
||||
|
||||
// <Definition of class [[GUSIMTTcpFactory]]>=
|
||||
class GUSIMTTcpFactory : public GUSISocketFactory {
|
||||
public:
|
||||
static GUSISocketFactory * Instance();
|
||||
virtual GUSISocket * socket(int domain, int type, int protocol);
|
||||
private:
|
||||
GUSIMTTcpFactory() {}
|
||||
static GUSISocketFactory * instance;
|
||||
};
|
||||
|
||||
// <Inline member functions for class [[GUSIMTTcpFactory]]>=
|
||||
inline GUSISocketFactory * GUSIMTTcpFactory::Instance()
|
||||
{
|
||||
if (!instance)
|
||||
instance = new GUSIMTTcpFactory;
|
||||
return instance;
|
||||
}
|
||||
|
||||
#endif /* GUSI_INTERNAL */
|
||||
|
||||
#endif /* GUSI_SOURCE */
|
||||
|
||||
#endif /* _GUSIMTTcp_ */
|
|
@ -1,95 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSIMTUdp.nw - UDP code for MacTCP
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.11 2000/10/16 04:02:00 neeri
|
||||
// % Save A5 in completion routines
|
||||
// %
|
||||
// % Revision 1.10 2000/05/23 07:05:16 neeri
|
||||
// % Improve formatting
|
||||
// %
|
||||
// % Revision 1.9 2000/03/06 06:10:01 neeri
|
||||
// % Reorganize Yield()
|
||||
// %
|
||||
// % Revision 1.8 1999/08/26 05:45:04 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.7 1999/08/02 07:02:44 neeri
|
||||
// % Support for asynchronous errors and other socket options
|
||||
// %
|
||||
// % Revision 1.6 1999/07/20 04:25:53 neeri
|
||||
// % Fixed race condition in sendto()
|
||||
// %
|
||||
// % Revision 1.5 1999/06/28 06:04:59 neeri
|
||||
// % Support interrupted calls
|
||||
// %
|
||||
// % Revision 1.4 1999/05/29 06:26:44 neeri
|
||||
// % Fixed header guards
|
||||
// %
|
||||
// % Revision 1.3 1999/03/17 09:05:09 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// % Revision 1.2 1998/11/22 23:06:57 neeri
|
||||
// % Releasing 2.0a4 in a hurry
|
||||
// %
|
||||
// % Revision 1.1 1998/10/25 11:57:37 neeri
|
||||
// % Ready to release 2.0a3
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{MacTCP UDP sockets}
|
||||
//
|
||||
// A [[GUSIMTUdpSocket]] implements the UDP socket class for MacTCP. All instances
|
||||
// of [[GUSIMTUdpSocket]] are created by the [[GUSIMTUdpFactory]] singleton, so
|
||||
// there is no point in exporting the class itself.
|
||||
//
|
||||
// <GUSIMTUdp.h>=
|
||||
#ifndef _GUSIMTUdp_
|
||||
#define _GUSIMTUdp_
|
||||
|
||||
#ifdef GUSI_SOURCE
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
// \section{Definition of [[GUSIMTUdpFactory]]}
|
||||
//
|
||||
// [[GUSIMTUdpFactory]] is a singleton subclass of [[GUSISocketFactory]].
|
||||
//
|
||||
// <Definition of [[GUSIwithMTUdpSockets]]>=
|
||||
void GUSIwithMTUdpSockets();
|
||||
__END_DECLS
|
||||
|
||||
#ifdef GUSI_INTERNAL
|
||||
|
||||
#include "GUSIFactory.h"
|
||||
|
||||
// <Definition of class [[GUSIMTUdpFactory]]>=
|
||||
class GUSIMTUdpFactory : public GUSISocketFactory {
|
||||
public:
|
||||
static GUSISocketFactory * Instance();
|
||||
virtual GUSISocket * socket(int domain, int type, int protocol);
|
||||
private:
|
||||
GUSIMTUdpFactory() {}
|
||||
static GUSISocketFactory * instance;
|
||||
};
|
||||
|
||||
// <Inline member functions for class [[GUSIMTUdpFactory]]>=
|
||||
inline GUSISocketFactory * GUSIMTUdpFactory::Instance()
|
||||
{
|
||||
if (!instance)
|
||||
instance = new GUSIMTUdpFactory;
|
||||
return instance;
|
||||
}
|
||||
|
||||
#endif /* GUSI_INTERNAL */
|
||||
|
||||
#endif /* GUSI_SOURCE */
|
||||
|
||||
#endif /* _GUSIMTUdp_ */
|
|
@ -1,178 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSIMacFile.nw - Disk files
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.24 2001/01/17 08:58:06 neeri
|
||||
// % Releasing 2.1.4
|
||||
// %
|
||||
// % Revision 1.23 2000/12/23 06:11:36 neeri
|
||||
// % Move diagnostics to A5 safe time
|
||||
// %
|
||||
// % Revision 1.22 2000/10/16 04:02:00 neeri
|
||||
// % Save A5 in completion routines
|
||||
// %
|
||||
// % Revision 1.21 2000/05/23 07:07:05 neeri
|
||||
// % Improve formatting, fix lseek for readonly files
|
||||
// %
|
||||
// % Revision 1.20 2000/03/15 07:17:11 neeri
|
||||
// % Fix rename for existing targets
|
||||
// %
|
||||
// % Revision 1.19 2000/03/06 08:12:27 neeri
|
||||
// % New Yield system; fix readdir at end of directory
|
||||
// %
|
||||
// % Revision 1.18 1999/11/15 07:24:32 neeri
|
||||
// % Return error for stat() of nonexistent files.
|
||||
// %
|
||||
// % Revision 1.17 1999/09/09 07:19:19 neeri
|
||||
// % Fix read-ahead switch-off
|
||||
// %
|
||||
// % Revision 1.16 1999/08/26 05:45:05 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.15 1999/08/05 05:55:35 neeri
|
||||
// % Updated for CW Pro 5
|
||||
// %
|
||||
// % Revision 1.14 1999/08/02 07:02:45 neeri
|
||||
// % Support for asynchronous errors and other socket options
|
||||
// %
|
||||
// % Revision 1.13 1999/07/19 06:21:03 neeri
|
||||
// % Add mkdir/rmdir, fix various file manager related bugs
|
||||
// %
|
||||
// % Revision 1.12 1999/07/07 04:17:41 neeri
|
||||
// % Final tweaks for 2.0b3
|
||||
// %
|
||||
// % Revision 1.11 1999/06/28 06:07:15 neeri
|
||||
// % Support I/O alignment, more effective writeback strategy
|
||||
// %
|
||||
// % Revision 1.10 1999/05/30 02:18:05 neeri
|
||||
// % Cleaner definition of GUSICatInfo
|
||||
// %
|
||||
// % Revision 1.9 1999/04/29 05:33:19 neeri
|
||||
// % Fix fcntl prototype
|
||||
// %
|
||||
// % Revision 1.8 1999/04/10 04:54:39 neeri
|
||||
// % stat() was broken for directories
|
||||
// %
|
||||
// % Revision 1.7 1999/03/29 09:51:28 neeri
|
||||
// % New configuration system with support for hardcoded configurations.
|
||||
// %
|
||||
// % Revision 1.6 1999/03/17 09:05:09 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// % Revision 1.5 1998/11/22 23:06:57 neeri
|
||||
// % Releasing 2.0a4 in a hurry
|
||||
// %
|
||||
// % Revision 1.4 1998/10/11 16:45:19 neeri
|
||||
// % Ready to release 2.0a2
|
||||
// %
|
||||
// % Revision 1.3 1998/08/01 21:28:58 neeri
|
||||
// % Add directory operations
|
||||
// %
|
||||
// % Revision 1.2 1998/02/11 12:57:14 neeri
|
||||
// % PowerPC Build
|
||||
// %
|
||||
// % Revision 1.1 1998/01/25 21:02:48 neeri
|
||||
// % Engine implemented, except for signals & scheduling
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{Disk files}
|
||||
//
|
||||
// A [[GUSIMacFileSocket]] implements the operations on mac files. All instances
|
||||
// of [[GUSIMacFileSocket]] are created by the [[GUSIMacFileDevice]] singleton, so
|
||||
// there is no point in exporting the class itself.
|
||||
//
|
||||
// A [[GUSIMacDirectory]] implements directory handles on mac directories.
|
||||
//
|
||||
// <GUSIMacFile.h>=
|
||||
#ifndef _GUSIMacFile_
|
||||
#define _GUSIMacFile_
|
||||
|
||||
#ifdef GUSI_INTERNAL
|
||||
|
||||
#include "GUSIDevice.h"
|
||||
|
||||
// \section{Definition of [[GUSIMacFileDevice]]}
|
||||
//
|
||||
// [[GUSIMacFileDevice]] is a singleton subclass of [[GUSIDevice]].
|
||||
//
|
||||
// <Definition of class [[GUSIMacFileDevice]]>=
|
||||
class GUSIMacFileDevice : public GUSIDevice {
|
||||
public:
|
||||
static GUSIMacFileDevice * Instance();
|
||||
virtual bool Want(GUSIFileToken & file);
|
||||
|
||||
// <Overridden member functions for [[GUSIMacFileDevice]]>=
|
||||
virtual GUSISocket * open(GUSIFileToken & file, int flags);
|
||||
// The normal case of [[remove]] is straightforward, but we also want to support
|
||||
// the removing of open files, which is frequently used in POSIX code, as much
|
||||
// as possible.
|
||||
//
|
||||
// <Overridden member functions for [[GUSIMacFileDevice]]>=
|
||||
virtual int remove(GUSIFileToken & file);
|
||||
// [[rename]] can be a surprisingly difficult operation.
|
||||
//
|
||||
// <Overridden member functions for [[GUSIMacFileDevice]]>=
|
||||
virtual int rename(GUSIFileToken & file, const char * newname);
|
||||
// [[stat]] is a rather intimidating function which needs to pull together
|
||||
// information from various sources.
|
||||
//
|
||||
// <Overridden member functions for [[GUSIMacFileDevice]]>=
|
||||
virtual int stat(GUSIFileToken & file, struct stat * buf);
|
||||
// <Overridden member functions for [[GUSIMacFileDevice]]>=
|
||||
virtual int chmod(GUSIFileToken & file, mode_t mode);
|
||||
// <Overridden member functions for [[GUSIMacFileDevice]]>=
|
||||
virtual int utime(GUSIFileToken & file, const utimbuf * times);
|
||||
// <Overridden member functions for [[GUSIMacFileDevice]]>=
|
||||
virtual int access(GUSIFileToken & file, int mode);
|
||||
// <Overridden member functions for [[GUSIMacFileDevice]]>=
|
||||
virtual int mkdir(GUSIFileToken & file);
|
||||
// <Overridden member functions for [[GUSIMacFileDevice]]>=
|
||||
virtual int rmdir(GUSIFileToken & file);
|
||||
// <Overridden member functions for [[GUSIMacFileDevice]]>=
|
||||
virtual GUSIDirectory * opendir(GUSIFileToken & file);
|
||||
// [[symlink]] has to reproduce the Finder's alias creation process, which is
|
||||
// quite complex.
|
||||
//
|
||||
// <Overridden member functions for [[GUSIMacFileDevice]]>=
|
||||
virtual int symlink(GUSIFileToken & to, const char * newlink);
|
||||
// <Overridden member functions for [[GUSIMacFileDevice]]>=
|
||||
virtual int readlink(GUSIFileToken & link, char * buf, int bufsize);
|
||||
// <Overridden member functions for [[GUSIMacFileDevice]]>=
|
||||
virtual int fgetfileinfo(GUSIFileToken & file, OSType * creator, OSType * type);
|
||||
virtual int fsetfileinfo(GUSIFileToken & file, OSType creator, OSType type);
|
||||
// [[faccess]] is a somewhat curious case in that [[GUSIMacFileDevice]]
|
||||
// accepts responsibility for handling it, but then does not, in fact, handle
|
||||
// it.
|
||||
//
|
||||
// <Overridden member functions for [[GUSIMacFileDevice]]>=
|
||||
virtual int faccess(GUSIFileToken & file, unsigned * cmd, void * arg);
|
||||
|
||||
GUSISocket * open(short fileRef, int flags);
|
||||
|
||||
int MarkTemporary(const FSSpec & file);
|
||||
void CleanupTemporaries(bool giveup);
|
||||
|
||||
~GUSIMacFileDevice();
|
||||
protected:
|
||||
GUSIMacFileDevice() : fTemporaries(0) {}
|
||||
|
||||
// [[MarkTemporary]] moves the file to the temporary folder and puts it on a list
|
||||
// of death candidates.
|
||||
//
|
||||
// <Privatissima of [[GUSIMacFileDevice]]>=
|
||||
struct TempQueue {
|
||||
TempQueue * fNext;
|
||||
FSSpec fSpec;
|
||||
} * fTemporaries;
|
||||
};
|
||||
|
||||
#endif /* GUSI_INTERNAL */
|
||||
|
||||
#endif /* _GUSIMacFile_ */
|
|
@ -1,266 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSINetDB.nw - Convert between names and adresses
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.10 2000/12/23 06:11:55 neeri
|
||||
// % Add SSH service
|
||||
// %
|
||||
// % Revision 1.9 2000/05/23 07:10:35 neeri
|
||||
// % Improve formatting
|
||||
// %
|
||||
// % Revision 1.8 2000/03/15 07:18:43 neeri
|
||||
// % Fix GUSIBuiltinServiceDB::sServices
|
||||
// %
|
||||
// % Revision 1.7 1999/11/15 07:23:23 neeri
|
||||
// % Fix gethostname for non-TCP/IP case
|
||||
// %
|
||||
// % Revision 1.6 1999/08/26 05:45:05 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.5 1999/05/30 03:09:30 neeri
|
||||
// % Added support for MPW compilers
|
||||
// %
|
||||
// % Revision 1.4 1999/03/17 09:05:10 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// % Revision 1.3 1998/11/22 23:06:58 neeri
|
||||
// % Releasing 2.0a4 in a hurry
|
||||
// %
|
||||
// % Revision 1.2 1998/10/25 11:33:38 neeri
|
||||
// % Fixed disastrous bug in inet_addr, support alternative NL conventions
|
||||
// %
|
||||
// % Revision 1.1 1998/10/11 16:45:20 neeri
|
||||
// % Ready to release 2.0a2
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{Converting Between Names and IP Addresses}
|
||||
//
|
||||
// The [[GUSINetDB]] class coordinates access to the domain name server database.
|
||||
//
|
||||
// The [[GUSIServiceDB]] class is responsible for a database of TCP/IP service
|
||||
// name to port number mappings.
|
||||
//
|
||||
// The [[hostent]] and [[servent]] classes are somewhat inconvenient to set up as
|
||||
// they reference extra chunks of memory, so we define the wrapper classes
|
||||
// [[GUSIhostent]] and [[GUSIservent]].
|
||||
//
|
||||
// <GUSINetDB.h>=
|
||||
#ifndef _GUSINetDB_
|
||||
#define _GUSINetDB_
|
||||
|
||||
#ifdef GUSI_SOURCE
|
||||
#include "GUSISpecific.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <ConditionalMacros.h>
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=native
|
||||
#endif
|
||||
|
||||
// \section{Definition of [[GUSIhostent]] and [[GUSIservent]]}
|
||||
//
|
||||
// A [[GUSIhostent]] may need a lot of data, so we allocate the name data
|
||||
// dynamically.
|
||||
//
|
||||
// <Definition of class [[GUSIhostent]]>=
|
||||
class GUSIhostent : public hostent {
|
||||
public:
|
||||
GUSIhostent();
|
||||
|
||||
void Alloc(size_t size);
|
||||
|
||||
char * fAlias[16];
|
||||
char * fAddressList[16];
|
||||
char * fName;
|
||||
size_t fAlloc;
|
||||
char fAddrString[16];
|
||||
};
|
||||
|
||||
extern "C" void GUSIKillHostEnt(void * hostent);
|
||||
|
||||
// A [[GUSIservent]] typically will remain more modest in its needs, so the
|
||||
// data is allocated statically.
|
||||
//
|
||||
// <Definition of class [[GUSIservent]]>=
|
||||
class GUSIservent : public servent {
|
||||
public:
|
||||
GUSIservent();
|
||||
|
||||
char * fAlias[8];
|
||||
char fName[256];
|
||||
};
|
||||
// \section{Definition of [[GUSIServiceDB]]}
|
||||
//
|
||||
// [[GUSIServiceDB]] is a singleton, used as a primitive iterator. The semantics of
|
||||
// these iterators conform only very superficially to real iterators:
|
||||
//
|
||||
// \begin{itemize}
|
||||
// \item Only a single instance of the iterator is supported.
|
||||
// \item Comparison operators all compare against [[end]], no matter what
|
||||
// arguments are passed.
|
||||
// \end{itemize}
|
||||
//
|
||||
// <Definition of class [[GUSIServiceDB]]>=
|
||||
extern "C" void GUSIKillServiceDBData(void * entry);
|
||||
|
||||
class GUSIServiceDB {
|
||||
public:
|
||||
static GUSIServiceDB * Instance();
|
||||
// Iterating is accomplished by a public interface conforming to STL iterator
|
||||
// protocols.
|
||||
//
|
||||
// <Iterating over the [[GUSIServiceDB]]>=
|
||||
class iterator {
|
||||
public:
|
||||
inline bool operator==(const iterator & other);
|
||||
inline bool operator!=(const iterator & other);
|
||||
inline iterator & operator++();
|
||||
inline servent * operator*();
|
||||
};
|
||||
inline static iterator begin();
|
||||
inline static iterator end();
|
||||
protected:
|
||||
static GUSIServiceDB * sInstance;
|
||||
GUSIServiceDB() {}
|
||||
virtual ~GUSIServiceDB() {}
|
||||
|
||||
friend void GUSIKillServiceDBData(void * entry);
|
||||
|
||||
// This interface does not access any data elements in the iterator, but directly
|
||||
// calls through to a private interface in the [[GUSIServiceDB]], which explains
|
||||
// the limitations in the iterator implementation.
|
||||
//
|
||||
// <Internal iterator protocol of [[GUSIServiceDB]]>=
|
||||
friend class iterator;
|
||||
|
||||
class Data {
|
||||
public:
|
||||
Data() : fCurrent(0) {}
|
||||
|
||||
servent * fCurrent;
|
||||
GUSIservent fServent;
|
||||
};
|
||||
typedef GUSISpecificData<Data, GUSIKillServiceDBData> SpecificData;
|
||||
static SpecificData sData;
|
||||
|
||||
virtual void Reset() = 0;
|
||||
virtual void Next() = 0;
|
||||
};
|
||||
// \section{Definition of [[GUSINetDB]]}
|
||||
//
|
||||
//
|
||||
// <Definition of class [[GUSINetDB]]>=
|
||||
class GUSINetDB {
|
||||
public:
|
||||
// [[GUSINetDB]] is a singleton, but usually instantiated by an instance of a
|
||||
// derived class.
|
||||
//
|
||||
// <Constructing instances of [[GUSINetDB]]>=
|
||||
static GUSINetDB * Instance();
|
||||
// The public interface of [[GUSINetDB]] consists of three areas. The first set of
|
||||
// calls is concerned with host names and IP numbers.
|
||||
//
|
||||
// <[[GUSINetDB]] host database>=
|
||||
virtual hostent * gethostbyname(const char * name);
|
||||
virtual hostent * gethostbyaddr(const void * addr, size_t len, int type);
|
||||
virtual char * inet_ntoa(in_addr inaddr);
|
||||
virtual in_addr_t inet_addr(const char *address);
|
||||
virtual long gethostid();
|
||||
virtual int gethostname(char *machname, int buflen);
|
||||
// The next set of calls is concerned with TCP and UDP services.
|
||||
//
|
||||
// <[[GUSINetDB]] service database>=
|
||||
virtual servent * getservbyname(const char * name, const char * proto);
|
||||
virtual servent * getservbyport(int port, const char * proto);
|
||||
virtual servent * getservent();
|
||||
virtual void setservent(int stayopen);
|
||||
virtual void endservent();
|
||||
// Finally, there is a set of calls concerned with protocols.
|
||||
//
|
||||
// <[[GUSINetDB]] protocol database>=
|
||||
virtual protoent * getprotobyname(const char * name);
|
||||
virtual protoent * getprotobynumber(int proto);
|
||||
virtual protoent * getprotoent();
|
||||
virtual void setprotoent(int stayopen);
|
||||
virtual void endprotoent();
|
||||
protected:
|
||||
GUSINetDB();
|
||||
virtual ~GUSINetDB() {}
|
||||
// \section{Implementation of [[GUSINetDB]]}
|
||||
//
|
||||
// [[GUSINetDB]] is a singleton, but typically implemented by an instance
|
||||
// of a subclass (stored into [[fInstance]] by that subclass) rather than the
|
||||
// base class.
|
||||
//
|
||||
// <Privatissima of [[GUSINetDB]]>=
|
||||
static GUSINetDB * sInstance;
|
||||
// The service database is implemented in terms of [[GUSIServiceDB]]. Only
|
||||
// [[getservent]] and [[setservent]] accesse [[GUSIServiceDB]] directly, however.
|
||||
//
|
||||
// <Privatissima of [[GUSINetDB]]>=
|
||||
bool fServiceOpen;
|
||||
GUSIServiceDB::iterator fServiceIter;
|
||||
// The protocol database is similar, in principle, to the service database, but it
|
||||
// lends itself naturally to a much simpler implementation.
|
||||
//
|
||||
// <Privatissima of [[GUSINetDB]]>=
|
||||
int fNextProtocol;
|
||||
static protoent sProtocols[2];
|
||||
};
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=reset
|
||||
#endif
|
||||
|
||||
#ifdef GUSI_INTERNAL
|
||||
|
||||
// Iterators can be defined without regard to the implementation of the
|
||||
// [[GUSIServiceDB]] currently used.
|
||||
//
|
||||
// <Inline member functions for class [[GUSIServiceDB]]>=
|
||||
GUSIServiceDB::iterator GUSIServiceDB::begin()
|
||||
{
|
||||
Instance()->Reset();
|
||||
Instance()->Next();
|
||||
|
||||
return iterator();
|
||||
}
|
||||
GUSIServiceDB::iterator GUSIServiceDB::end()
|
||||
{
|
||||
return iterator();
|
||||
}
|
||||
bool GUSIServiceDB::iterator::operator==(const GUSIServiceDB::iterator &)
|
||||
{
|
||||
return !GUSIServiceDB::sData->fCurrent;
|
||||
}
|
||||
bool GUSIServiceDB::iterator::operator!=(const GUSIServiceDB::iterator &)
|
||||
{
|
||||
return GUSIServiceDB::sData->fCurrent
|
||||
== static_cast<servent *>(nil);
|
||||
}
|
||||
GUSIServiceDB::iterator & GUSIServiceDB::iterator::operator++()
|
||||
{
|
||||
GUSIServiceDB::Instance()->Next();
|
||||
return *this;
|
||||
}
|
||||
servent * GUSIServiceDB::iterator::operator*()
|
||||
{
|
||||
return GUSIServiceDB::sData->fCurrent;
|
||||
}
|
||||
|
||||
#endif /* GUSI_INTERNAL */
|
||||
|
||||
#endif /* GUSI_SOURCE */
|
||||
|
||||
#endif /* _GUSINetDB_ */
|
|
@ -1,75 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSINull.nw - Null device
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.7 2000/03/06 06:03:29 neeri
|
||||
// % Check device families for file paths
|
||||
// %
|
||||
// % Revision 1.6 1999/08/26 05:45:05 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.5 1999/05/29 06:26:44 neeri
|
||||
// % Fixed header guards
|
||||
// %
|
||||
// % Revision 1.4 1999/04/29 05:34:22 neeri
|
||||
// % Support stat/fstat
|
||||
// %
|
||||
// % Revision 1.3 1999/03/17 09:05:10 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// % Revision 1.2 1998/11/22 23:06:59 neeri
|
||||
// % Releasing 2.0a4 in a hurry
|
||||
// %
|
||||
// % Revision 1.1 1998/08/01 21:32:09 neeri
|
||||
// % About ready for 2.0a1
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{Null device}
|
||||
//
|
||||
// A [[GUSINullSocket]] implements the null socket class for MacTCP. All instances
|
||||
// of [[GUSINullSocket]] are created by the [[GUSINullDevice]] singleton, so
|
||||
// there is no point in exporting the class itself.
|
||||
//
|
||||
// <GUSINull.h>=
|
||||
#ifndef _GUSINull_
|
||||
#define _GUSINull_
|
||||
|
||||
#ifdef GUSI_INTERNAL
|
||||
|
||||
#include "GUSIDevice.h"
|
||||
|
||||
// \section{Definition of [[GUSINullDevice]]}
|
||||
//
|
||||
// [[GUSINullDevice]] is a singleton subclass of [[GUSIDevice]].
|
||||
//
|
||||
// <Definition of class [[GUSINullDevice]]>=
|
||||
class GUSINullDevice : public GUSIDevice {
|
||||
public:
|
||||
static GUSINullDevice * Instance();
|
||||
virtual bool Want(GUSIFileToken & file);
|
||||
virtual GUSISocket * open(GUSIFileToken & file, int flags);
|
||||
virtual int stat(GUSIFileToken & file, struct stat * buf);
|
||||
GUSISocket * open();
|
||||
protected:
|
||||
GUSINullDevice() {}
|
||||
static GUSINullDevice * sInstance;
|
||||
};
|
||||
|
||||
// <Inline member functions for class [[GUSINullDevice]]>=
|
||||
inline GUSINullDevice * GUSINullDevice::Instance()
|
||||
{
|
||||
if (!sInstance)
|
||||
sInstance = new GUSINullDevice;
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
#endif /* GUSI_INTERNAL */
|
||||
|
||||
#endif /* _GUSINull_ */
|
|
@ -1,71 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSIOpenTransport.nw- OpenTransport sockets
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.11 2001/01/17 08:54:12 neeri
|
||||
// % Add Clone() implementations
|
||||
// %
|
||||
// % Revision 1.10 2000/06/12 04:20:59 neeri
|
||||
// % Introduce GUSI_*printf
|
||||
// %
|
||||
// % Revision 1.9 2000/05/23 09:05:27 neeri
|
||||
// % Improve formatting
|
||||
// %
|
||||
// % Revision 1.8 1999/09/26 03:57:12 neeri
|
||||
// % Renamed broadcast option
|
||||
// %
|
||||
// % Revision 1.7 1999/09/09 07:20:29 neeri
|
||||
// % Fix numerous bugs, add support for interface ioctls
|
||||
// %
|
||||
// % Revision 1.6 1999/08/26 05:45:06 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.5 1999/08/02 07:02:45 neeri
|
||||
// % Support for asynchronous errors and other socket options
|
||||
// %
|
||||
// % Revision 1.4 1999/05/29 06:26:44 neeri
|
||||
// % Fixed header guards
|
||||
// %
|
||||
// % Revision 1.3 1999/04/14 04:21:19 neeri
|
||||
// % Correct option sizes
|
||||
// %
|
||||
// % Revision 1.2 1999/04/10 05:17:51 neeri
|
||||
// % Implement broadcast/multicast options
|
||||
// %
|
||||
// % Revision 1.1 1999/03/17 09:05:10 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{Open Transport TCP/IP sockets}
|
||||
//
|
||||
// For TCP and UDP, the strategy classes do most of the work, the derived socket
|
||||
// classes only have to do option management.
|
||||
//
|
||||
// <GUSIOTInet.h>=
|
||||
#ifndef _GUSIOTInet_
|
||||
#define _GUSIOTInet_
|
||||
|
||||
#ifdef GUSI_SOURCE
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
// \section{Definition of Open Transport Internet hooks}
|
||||
//
|
||||
//
|
||||
// <Definition of [[GUSIwithOTInetSockets]]>=
|
||||
void GUSIwithOTInetSockets();
|
||||
void GUSIwithOTTcpSockets();
|
||||
void GUSIwithOTUdpSockets();
|
||||
__END_DECLS
|
||||
|
||||
#endif /* GUSI_SOURCE */
|
||||
|
||||
#endif /* _GUSIOTInet_ */
|
|
@ -1,93 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSIOTNetDB.nw - Open Transport DNS lookups
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.8 2000/06/12 04:20:59 neeri
|
||||
// % Introduce GUSI_*printf
|
||||
// %
|
||||
// % Revision 1.7 2000/05/23 07:11:45 neeri
|
||||
// % Improve formatting, handle failed lookups correctly
|
||||
// %
|
||||
// % Revision 1.6 2000/03/06 06:10:01 neeri
|
||||
// % Reorganize Yield()
|
||||
// %
|
||||
// % Revision 1.5 1999/12/14 06:27:47 neeri
|
||||
// % initialize OT before opening resolver
|
||||
// %
|
||||
// % Revision 1.4 1999/08/26 05:45:06 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.3 1999/06/30 07:42:06 neeri
|
||||
// % Getting ready to release 2.0b3
|
||||
// %
|
||||
// % Revision 1.2 1999/05/30 03:09:31 neeri
|
||||
// % Added support for MPW compilers
|
||||
// %
|
||||
// % Revision 1.1 1999/03/17 09:05:10 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{IP Name Lookup in Open Transport}
|
||||
//
|
||||
//
|
||||
// <GUSIOTNetDB.h>=
|
||||
#ifndef _GUSIOTNetDB_
|
||||
#define _GUSIOTNetDB_
|
||||
|
||||
#ifdef GUSI_INTERNAL
|
||||
#include "GUSINetDB.h"
|
||||
#include "GUSIContext.h"
|
||||
#include "GUSIOpenTransport.h"
|
||||
|
||||
// \section{Definition of [[GUSIOTNetDB]]}
|
||||
//
|
||||
// We don't want to open the Open Transport headers files in our public header, but we
|
||||
// need [[InetSvcRef]].
|
||||
//
|
||||
// <Name dropping for file GUSIOTNetDB>=
|
||||
class TInternetServices;
|
||||
typedef TInternetServices* InetSvcRef;
|
||||
|
||||
// <Definition of class [[GUSIOTNetDB]]>=
|
||||
class GUSIOTNetDB : public GUSINetDB {
|
||||
public:
|
||||
static void Instantiate();
|
||||
bool Resolver();
|
||||
|
||||
// <Overridden member functions for [[GUSIOTNetDB]]>=
|
||||
virtual hostent * gethostbyname(const char * name);
|
||||
// <Overridden member functions for [[GUSIOTNetDB]]>=
|
||||
virtual hostent * gethostbyaddr(const void * addr, size_t len, int type);
|
||||
// <Overridden member functions for [[GUSIOTNetDB]]>=
|
||||
virtual char * inet_ntoa(in_addr inaddr);
|
||||
// <Overridden member functions for [[GUSIOTNetDB]]>=
|
||||
virtual long gethostid();
|
||||
private:
|
||||
GUSISpecificData<GUSIhostent, GUSIKillHostEnt> fHost;
|
||||
// \section{Implementation of [[GUSIOTNetDB]]}
|
||||
//
|
||||
//
|
||||
// <Privatissima of [[GUSIOTNetDB]]>=
|
||||
GUSIOTNetDB();
|
||||
// The [[GUSIOTNetDB]] notifier operates similarly to the [[GUSIOTSocket]] notifier,
|
||||
// but it has to get the context to wake up somehow from its parameters.
|
||||
//
|
||||
// <Privatissima of [[GUSIOTNetDB]]>=
|
||||
uint16_t fEvent;
|
||||
uint32_t fCompletion;
|
||||
OSStatus fAsyncError;
|
||||
InetSvcRef fSvc;
|
||||
GUSIContext * fCreationContext;
|
||||
friend pascal void GUSIOTNetDBNotify(GUSIOTNetDB *, OTEventCode, OTResult, void *);
|
||||
};
|
||||
|
||||
#endif /* GUSI_INTERNAL */
|
||||
|
||||
#endif /* _GUSIOTNetDB_ */
|
|
@ -1,456 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSIOpenTransport.nw- OpenTransport sockets
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.2 2001/03/28 14:04:32 chombier
|
||||
// % GUSI 2.1.6b2 update
|
||||
// %
|
||||
// % Revision 1.21 2001/03/20 08:12:55 neeri
|
||||
// % Further select repairs
|
||||
// %
|
||||
// % Revision 1.20 2001/03/20 02:35:21 neeri
|
||||
// % Refined new select() implementation
|
||||
// %
|
||||
// % Revision 1.19 2001/03/09 09:25:21 neeri
|
||||
// % Fixed select logic bugs, listener queue
|
||||
// %
|
||||
// % Revision 1.18 2001/01/17 08:58:06 neeri
|
||||
// % Releasing 2.1.4
|
||||
// %
|
||||
// % Revision 1.17 2000/10/16 04:07:23 neeri
|
||||
// % Fix accept code
|
||||
// %
|
||||
// % Revision 1.16 2000/06/01 06:31:10 neeri
|
||||
// % Reset shutdown flags on connect, refine test for data available, fix memory leak in UDP sendto
|
||||
// %
|
||||
// % Revision 1.15 2000/05/23 07:13:19 neeri
|
||||
// % Improve formatting, implement immediate close and sorrect linger handling
|
||||
// %
|
||||
// % Revision 1.14 2000/03/15 07:19:53 neeri
|
||||
// % Fix numerous race conditions
|
||||
// %
|
||||
// % Revision 1.13 2000/03/06 06:10:01 neeri
|
||||
// % Reorganize Yield()
|
||||
// %
|
||||
// % Revision 1.12 1999/12/14 06:28:29 neeri
|
||||
// % Read pending data while closing
|
||||
// %
|
||||
// % Revision 1.11 1999/12/13 02:44:19 neeri
|
||||
// % Fix SO_LINGER, read results for disconnected sockets
|
||||
// %
|
||||
// % Revision 1.10 1999/10/15 02:48:50 neeri
|
||||
// % Make disconnects orderly
|
||||
// %
|
||||
// % Revision 1.9 1999/09/09 07:20:29 neeri
|
||||
// % Fix numerous bugs, add support for interface ioctls
|
||||
// %
|
||||
// % Revision 1.8 1999/09/03 06:31:36 neeri
|
||||
// % Needed more mopups
|
||||
// %
|
||||
// % Revision 1.7 1999/08/26 05:43:09 neeri
|
||||
// % Supply missing Unbind
|
||||
// %
|
||||
// % Revision 1.6 1999/08/02 07:02:45 neeri
|
||||
// % Support for asynchronous errors and other socket options
|
||||
// %
|
||||
// % Revision 1.5 1999/07/19 06:17:44 neeri
|
||||
// % Fix nonblocking connect
|
||||
// %
|
||||
// % Revision 1.4 1999/06/28 06:04:59 neeri
|
||||
// % Support interrupted calls
|
||||
// %
|
||||
// % Revision 1.3 1999/05/30 03:06:41 neeri
|
||||
// % MPW compiler compatibility, fix select for datagram sockets
|
||||
// %
|
||||
// % Revision 1.2 1999/04/29 05:33:19 neeri
|
||||
// % Fix fcntl prototype
|
||||
// %
|
||||
// % Revision 1.1 1999/03/17 09:05:11 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{Open Transport socket infrastructure}
|
||||
//
|
||||
// A [[GUSIOTSocket]] defines a class of Open Transport sockets. Since most
|
||||
// families differ only in a few details, like address representation, we
|
||||
// abstract the typical differences in a strategy class [[GUSIOTStrategy]].
|
||||
//
|
||||
// <GUSIOpenTransport.h>=
|
||||
#ifndef _GUSIOpenTransport_
|
||||
#define _GUSIOpenTransport_
|
||||
|
||||
#ifdef GUSI_INTERNAL
|
||||
|
||||
#include "GUSISocket.h"
|
||||
#include "GUSISocketMixins.h"
|
||||
#include "GUSIFactory.h"
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
#undef O_ASYNC
|
||||
#undef O_NDELAY
|
||||
#undef O_NONBLOCK
|
||||
#undef SIGHUP
|
||||
#undef SIGURG
|
||||
#undef AF_INET
|
||||
#undef TCP_KEEPALIVE
|
||||
#undef TCP_NODELAY
|
||||
#undef TCP_MAXSEG
|
||||
|
||||
#if UNIVERSAL_INTERFACES_VERSION >= 0x0340
|
||||
#undef IP_OPTIONS
|
||||
#undef IP_TOS
|
||||
#undef IP_TTL
|
||||
#undef IP_REUSEADDR
|
||||
#undef IP_DONTROUTE
|
||||
#undef IP_BROADCAST
|
||||
#undef IP_HDRINCL
|
||||
#undef IP_RCVOPTS
|
||||
#undef IP_RCVDSTADDR
|
||||
#undef IP_MULTICAST_IF
|
||||
#undef IP_MULTICAST_TTL
|
||||
#undef IP_MULTICAST_LOOP
|
||||
#undef IP_ADD_MEMBERSHIP
|
||||
#undef IP_DROP_MEMBERSHIP
|
||||
#undef IP_RCVIFADDR
|
||||
|
||||
#undef SIGURG
|
||||
#endif
|
||||
|
||||
#include <OpenTransport.h>
|
||||
#include <OpenTptInternet.h>
|
||||
|
||||
// \section{Definition of [[GUSIOTStrategy]]}
|
||||
//
|
||||
// A [[GUSIOTStrategy]] contains all the tricky parts of each Open Transport
|
||||
// family.
|
||||
//
|
||||
// <Definition of class [[GUSIOTStrategy]]>=
|
||||
class GUSIOTStrategy {
|
||||
public:
|
||||
// [[CreateConfiguration]] creates an appropriate [[OTConfiguration]]. This
|
||||
// method is not virtual, as it relies on the strategy method
|
||||
// [[ConfigPath]].
|
||||
//
|
||||
// <Strategic interfaces for [[GUSIOTStrategy]]>=
|
||||
OTConfiguration * CreateConfiguration();
|
||||
// [[PackAddress]] converts a socket address into an OT address, and
|
||||
// [[UnpackAddress]] performs the reverse step. [[CopyAddress]] copies an address.
|
||||
//
|
||||
// <Strategic interfaces for [[GUSIOTStrategy]]>=
|
||||
virtual int PackAddress(
|
||||
const void * address, socklen_t len, TNetbuf & addr, bool non_null = false) = 0;
|
||||
virtual int UnpackAddress(const TNetbuf & addr, void * address, socklen_t * len) = 0;
|
||||
virtual int CopyAddress(const TNetbuf & from, TNetbuf & to);
|
||||
// [[EndpointInfo]] returns a data structure storing endpoint parameters. We only
|
||||
// need one copy per socket type.
|
||||
//
|
||||
// <Strategic interfaces for [[GUSIOTStrategy]]>=
|
||||
TEndpointInfo * EndpointInfo() { return &fEndpointInfo; }
|
||||
protected:
|
||||
// <Privatissima of [[GUSIOTStrategy]]>=
|
||||
virtual const char * ConfigPath() = 0;
|
||||
// <Privatissima of [[GUSIOTStrategy]]>=
|
||||
TEndpointInfo fEndpointInfo;
|
||||
// \section{Implementation of [[GUSIOTStrategy]]}
|
||||
//
|
||||
// [[GUSIOTStrategy]] is mostly abstract, except for the [[CreateConfiguration]]
|
||||
// and [[CopyAddress]] methods.
|
||||
//
|
||||
// <Privatissima of [[GUSIOTStrategy]]>=
|
||||
OTConfiguration * fConfig;
|
||||
GUSIOTStrategy() : fConfig(nil) {}
|
||||
virtual ~GUSIOTStrategy();
|
||||
};
|
||||
// \section{Definition of [[GUSIOTFactory]] and descendants}
|
||||
//
|
||||
// A [[GUSIOTFactory]] is an abstract class combining a socket creation
|
||||
// mechanism with a strategy instance. To clarify our intent, we isolate
|
||||
// the latter in [[GUSIOTStrategy]].
|
||||
//
|
||||
// <Definition of class [[GUSIOTFactory]]>=
|
||||
class GUSIOTFactory : public GUSISocketFactory {
|
||||
public:
|
||||
static bool Initialize();
|
||||
protected:
|
||||
virtual GUSIOTStrategy *Strategy(int domain, int type, int protocol) = 0;
|
||||
private:
|
||||
// \section{Implementation of [[GUSIOTFactory]] and descendants}
|
||||
//
|
||||
//
|
||||
// <Privatissima of [[GUSIOTFactory]]>=
|
||||
static bool sOK;
|
||||
};
|
||||
// <Definition of class [[GUSIOTStreamFactory]]>=
|
||||
class GUSIOTStreamFactory : public GUSIOTFactory {
|
||||
public:
|
||||
GUSISocket * socket(int domain, int type, int protocol);
|
||||
};
|
||||
// <Definition of class [[GUSIOTDatagramFactory]]>=
|
||||
class GUSIOTDatagramFactory : public GUSIOTFactory {
|
||||
public:
|
||||
GUSISocket * socket(int domain, int type, int protocol);
|
||||
};
|
||||
// \section{Definition of [[GUSIOT]]}
|
||||
//
|
||||
// Open Transport allocates and deallocates many data structures, which we
|
||||
// simplify with a smart template. Allocation works via class allocation
|
||||
// operators, which is a bit weird admittedly.
|
||||
//
|
||||
// <Definition of template [[GUSIOT]]>=
|
||||
template <class T, int tag> class GUSIOT : public T {
|
||||
public:
|
||||
void * operator new(size_t, EndpointRef ref)
|
||||
{ OSStatus err; return OTAlloc(ref, tag, T_ALL, &err); }
|
||||
void * operator new(size_t, EndpointRef ref, int fields)
|
||||
{ OSStatus err; return OTAlloc(ref, tag, fields, &err); }
|
||||
void operator delete(void * o)
|
||||
{ if (o) OTFree(o, tag); }
|
||||
};
|
||||
template <class T, int tag> class GUSIOTAddr : public GUSIOT<T, tag> {
|
||||
public:
|
||||
int Pack(GUSIOTStrategy * strategy, const void * address, socklen_t len, bool non_null=false)
|
||||
{ return strategy->PackAddress(address, len, addr, non_null); }
|
||||
int Unpack(GUSIOTStrategy * strategy, void * address, socklen_t * len)
|
||||
{ return strategy->UnpackAddress(addr, address, len); }
|
||||
int Copy(GUSIOTStrategy * strategy, GUSIOTAddr<T, tag> * to)
|
||||
{ return strategy->CopyAddress(addr, to->addr); }
|
||||
};
|
||||
|
||||
typedef GUSIOTAddr<TBind, T_BIND> GUSIOTTBind;
|
||||
typedef GUSIOTAddr<TCall, T_CALL> GUSIOTTCall;
|
||||
typedef GUSIOTAddr<TUnitData, T_UNITDATA> GUSIOTTUnitData;
|
||||
typedef GUSIOTAddr<TUDErr, T_UDERROR> GUSIOTTUDErr;
|
||||
typedef GUSIOT<TDiscon, T_DIS> GUSIOTTDiscon;
|
||||
typedef GUSIOT<TOptMgmt, T_OPTMGMT> GUSIOTTOptMgmt;
|
||||
// \section{Definition of [[GUSIOTSocket]] and descendants}
|
||||
//
|
||||
// Open Transport sockets are rather lightweight, since OT is rather similar
|
||||
// to sockets already.
|
||||
//
|
||||
// <Definition of class [[GUSIOTSocket]]>=
|
||||
class GUSIOTSocket :
|
||||
public GUSISocket,
|
||||
protected GUSISMBlocking,
|
||||
protected GUSISMState,
|
||||
protected GUSISMAsyncError
|
||||
{
|
||||
public:
|
||||
// <Overridden member functions for [[GUSIOTSocket]]>=
|
||||
virtual int bind(void * name, socklen_t namelen);
|
||||
// [[getsockname]] and [[getpeername]] unpack the stored addresses.
|
||||
// Note that the reaction to [[nil]] addresses is a bit different.
|
||||
//
|
||||
// <Overridden member functions for [[GUSIOTSocket]]>=
|
||||
virtual int getsockname(void * name, socklen_t * namelen);
|
||||
// [[shutdown]] just delegates to [[GUSISMState]].
|
||||
//
|
||||
// <Overridden member functions for [[GUSIOTSocket]]>=
|
||||
virtual int shutdown(int how);
|
||||
// [[fcntl]] handles the blocking support.
|
||||
//
|
||||
// <Overridden member functions for [[GUSIOTSocket]]>=
|
||||
virtual int fcntl(int cmd, va_list arg);
|
||||
// [[ioctl]] deals with blocking support and with [[FIONREAD]].
|
||||
//
|
||||
// <Overridden member functions for [[GUSIOTSocket]]>=
|
||||
virtual int ioctl(unsigned int request, va_list arg);
|
||||
// Before we call [[select]], we check whether there is data currently available and turn
|
||||
// off the data flags otherwise.
|
||||
//
|
||||
// <Overridden member functions for [[GUSIOTSocket]]>=
|
||||
virtual bool pre_select(bool wantRead, bool wantWrite, bool wantExcept);
|
||||
// [[getsockopt]] and [[setsockopt]] are available for a variety of options.
|
||||
//
|
||||
// <Overridden member functions for [[GUSIOTSocket]]>=
|
||||
virtual int getsockopt(int level, int optname, void *optval, socklen_t * optlen);
|
||||
// <Overridden member functions for [[GUSIOTSocket]]>=
|
||||
virtual int setsockopt(int level, int optname, void *optval, socklen_t optlen);
|
||||
// Open Transport sockets implement socket style calls.
|
||||
//
|
||||
// <Overridden member functions for [[GUSIOTSocket]]>=
|
||||
virtual bool Supports(ConfigOption config);
|
||||
protected:
|
||||
GUSIOTSocket(GUSIOTStrategy * strategy);
|
||||
|
||||
// \section{Implementation of [[GUSIOTSocket]]}
|
||||
//
|
||||
// Open Transport may call this routine for dozens and dozens of different
|
||||
// reasons. Pretty much every call results in a wakeup of the threads attached
|
||||
// to the socket. We save some of the more interesting events in bitsets.
|
||||
// in [[MopupEvents]].
|
||||
//
|
||||
// <Privatissima of [[GUSIOTSocket]]>=
|
||||
uint16_t fNewEvent;
|
||||
uint16_t fCurEvent;
|
||||
uint16_t fEvent;
|
||||
uint32_t fNewCompletion;
|
||||
uint32_t fCurCompletion;
|
||||
uint32_t fCompletion;
|
||||
friend pascal void GUSIOTNotify(GUSIOTSocket *, OTEventCode, OTResult, void *);
|
||||
// To avoid race conditions with the notifier, we sometimes need a lock.
|
||||
//
|
||||
// <Privatissima of [[GUSIOTSocket]]>=
|
||||
class Lock {
|
||||
public:
|
||||
Lock(EndpointRef end) : fEndpoint(end) { OTEnterNotifier(fEndpoint); }
|
||||
~Lock() { OTLeaveNotifier(fEndpoint); }
|
||||
private:
|
||||
EndpointRef fEndpoint;
|
||||
};
|
||||
// For some events, we have to take a followup action at a more convenient time.
|
||||
//
|
||||
// <Privatissima of [[GUSIOTSocket]]>=
|
||||
virtual void MopupEvents();
|
||||
// [[GUSIOTSocket]] creates an asynchronous endpoint for the appropriate
|
||||
// provider.
|
||||
//
|
||||
// <Privatissima of [[GUSIOTSocket]]>=
|
||||
GUSIOTStrategy * fStrategy;
|
||||
EndpointRef fEndpoint;
|
||||
linger fLinger;
|
||||
UInt32 fDeadline;
|
||||
// The destructor tears down the connection as gracefully as possible. It also respects
|
||||
// the linger settings.
|
||||
//
|
||||
// <Privatissima of [[GUSIOTSocket]]>=
|
||||
virtual void close();
|
||||
virtual ~GUSIOTSocket();
|
||||
// [[Clone]] creates another socket of the same class.
|
||||
//
|
||||
// <Privatissima of [[GUSIOTSocket]]>=
|
||||
virtual GUSIOTSocket * Clone() = 0;
|
||||
// At the time the socket function [[bind]] is called, we are not really ready
|
||||
// yet to call [[OTBind]], but if we don't call it, we can't report whether the
|
||||
// address was free.
|
||||
//
|
||||
// <Privatissima of [[GUSIOTSocket]]>=
|
||||
GUSIOTTBind * fSockName;
|
||||
int BindToAddress(GUSIOTTBind * addr);
|
||||
// Open Transport takes unbinding a lot more serious than MacTCP.
|
||||
//
|
||||
// <Privatissima of [[GUSIOTSocket]]>=
|
||||
void Unbind();
|
||||
|
||||
friend class GUSIOTStreamSocket;
|
||||
friend class GUSIOTDatagramSocket;
|
||||
};
|
||||
// <Definition of class [[GUSIOTStreamSocket]]>=
|
||||
class GUSIOTStreamSocket : public GUSIOTSocket {
|
||||
public:
|
||||
// [[Clone]] creates another socket of the same class.
|
||||
//
|
||||
// <Overridden member functions for [[GUSIOTStreamSocket]]>=
|
||||
virtual GUSIOTSocket * Clone();
|
||||
// <Overridden member functions for [[GUSIOTStreamSocket]]>=
|
||||
virtual void close();
|
||||
virtual bool Close(UInt32 now);
|
||||
~GUSIOTStreamSocket();
|
||||
// Stream sockets include a mopup action for connect and disconnect.
|
||||
//
|
||||
// <Overridden member functions for [[GUSIOTStreamSocket]]>=
|
||||
virtual void MopupEvents();
|
||||
// [[listen]] is a bit embarassing, because we already committed ourselves
|
||||
// to a queue length of [[0]], so we have to unbind and rebind ourselves.
|
||||
//
|
||||
// <Overridden member functions for [[GUSIOTStreamSocket]]>=
|
||||
virtual int listen(int qlen);
|
||||
// <Overridden member functions for [[GUSIOTStreamSocket]]>=
|
||||
virtual int getpeername(void * name, socklen_t * namelen);
|
||||
// [[accept]] may become quite complex, because connections could nest. The
|
||||
// listening socket calls [[OTListen]], queues candidates by their
|
||||
// [[fNextListener]] field, and then trys calling [[OTAccept]] on the first
|
||||
// candidate.
|
||||
//
|
||||
// <Overridden member functions for [[GUSIOTStreamSocket]]>=
|
||||
virtual GUSISocket * accept(void * address, socklen_t * addrlen);
|
||||
// [[connect]] is comparatively simple.
|
||||
//
|
||||
// <Overridden member functions for [[GUSIOTStreamSocket]]>=
|
||||
virtual int connect(void * address, socklen_t addrlen);
|
||||
// Data transfer is simple as well. Here is the version for stream protocols.
|
||||
//
|
||||
// <Overridden member functions for [[GUSIOTStreamSocket]]>=
|
||||
virtual ssize_t recvfrom(const GUSIScatterer & buffer, int flags, void * from, socklen_t * fromlen);
|
||||
// <Overridden member functions for [[GUSIOTStreamSocket]]>=
|
||||
virtual ssize_t sendto(const GUSIGatherer & buffer, int flags, const void * to, socklen_t tolen);
|
||||
// [[select]] for stream sockets intermingles data information and connection
|
||||
// information as usual.
|
||||
//
|
||||
// <Overridden member functions for [[GUSIOTStreamSocket]]>=
|
||||
virtual bool select(bool * canRead, bool * canWrite, bool * except);
|
||||
// [[shutdown]] for stream sockets has to send an orderly disconnect.
|
||||
//
|
||||
// <Overridden member functions for [[GUSIOTStreamSocket]]>=
|
||||
virtual int shutdown(int how);
|
||||
protected:
|
||||
GUSIOTStreamSocket(GUSIOTStrategy * strategy);
|
||||
|
||||
// Since all we need to know is in the [[GUSIOTStrategy]], it often suffices
|
||||
// simply to create a [[GUSIOTSocket]]. Stream and datagram sockets differ
|
||||
// merely in the descendant they create.
|
||||
//
|
||||
// <Privatissima of [[GUSIOTStreamSocket]]>=
|
||||
friend class GUSIOTStreamFactory;
|
||||
// <Privatissima of [[GUSIOTStreamSocket]]>=
|
||||
friend pascal void GUSIOTNotify(GUSIOTSocket *, OTEventCode, OTResult, void *);
|
||||
// The peer address for a [[GUSIOTStreamSocket]] is stored in a [[GUSIOTTCall]]
|
||||
// structure.
|
||||
//
|
||||
// <Privatissima of [[GUSIOTStreamSocket]]>=
|
||||
GUSIOTTCall * fPeerName;
|
||||
// <Privatissima of [[GUSIOTStreamSocket]]>=
|
||||
GUSIOTStreamSocket * fNextListener;
|
||||
};
|
||||
// <Definition of class [[GUSIOTDatagramSocket]]>=
|
||||
class GUSIOTDatagramSocket : public GUSIOTSocket {
|
||||
public:
|
||||
// [[Clone]] creates another socket of the same class.
|
||||
//
|
||||
// <Overridden member functions for [[GUSIOTDatagramSocket]]>=
|
||||
virtual GUSIOTSocket * Clone();
|
||||
// <Overridden member functions for [[GUSIOTDatagramSocket]]>=
|
||||
~GUSIOTDatagramSocket();
|
||||
// <Overridden member functions for [[GUSIOTDatagramSocket]]>=
|
||||
virtual int getpeername(void * name, socklen_t * namelen);
|
||||
// A datagram socket can [[connect]] as many times as it wants.
|
||||
//
|
||||
// <Overridden member functions for [[GUSIOTDatagramSocket]]>=
|
||||
virtual int connect(void * address, socklen_t addrlen);
|
||||
// Datagram protocols use slightly different calls for data transfers.
|
||||
//
|
||||
// <Overridden member functions for [[GUSIOTDatagramSocket]]>=
|
||||
virtual ssize_t recvfrom(const GUSIScatterer & buffer, int flags, void * from, socklen_t * fromlen);
|
||||
// [[sendto]] needs either a valid [[to]] address or a stored peer address set by
|
||||
// [[connect]].
|
||||
//
|
||||
// <Overridden member functions for [[GUSIOTDatagramSocket]]>=
|
||||
virtual ssize_t sendto(const GUSIGatherer & buffer, int flags, const void * to, socklen_t tolen);
|
||||
// [[select]] for datagram sockets returns data information only.
|
||||
//
|
||||
// <Overridden member functions for [[GUSIOTDatagramSocket]]>=
|
||||
virtual bool select(bool * canRead, bool * canWrite, bool * except);
|
||||
protected:
|
||||
GUSIOTDatagramSocket(GUSIOTStrategy * strategy);
|
||||
|
||||
// <Privatissima of [[GUSIOTDatagramSocket]]>=
|
||||
friend class GUSIOTDatagramFactory;
|
||||
// Datagram sockets might be bound at rather arbitrary times.
|
||||
//
|
||||
// <Privatissima of [[GUSIOTDatagramSocket]]>=
|
||||
int BindIfUnbound();
|
||||
// The peer address for a [[GUSIOTDatagramSocket]] is stored in a [[GUSIOTTBind]]
|
||||
// structure.
|
||||
//
|
||||
// <Privatissima of [[GUSIOTDatagramSocket]]>=
|
||||
GUSIOTTBind * fPeerName;
|
||||
};
|
||||
|
||||
#endif /* GUSI_INTERNAL */
|
||||
|
||||
#endif /* _GUSIOpenTransport_ */
|
|
@ -1,115 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSIPOSIX.nw - POSIX/Socket wrappers
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.22 2001/01/17 08:58:06 neeri
|
||||
// % Releasing 2.1.4
|
||||
// %
|
||||
// % Revision 1.21 2000/10/29 18:36:32 neeri
|
||||
// % Fix time_t signedness issues
|
||||
// %
|
||||
// % Revision 1.20 2000/10/16 04:34:23 neeri
|
||||
// % Releasing 2.1.2
|
||||
// %
|
||||
// % Revision 1.19 2000/06/12 04:24:50 neeri
|
||||
// % Fix time, localtime, gmtime
|
||||
// %
|
||||
// % Revision 1.18 2000/05/23 07:15:30 neeri
|
||||
// % Improve formatting
|
||||
// %
|
||||
// % Revision 1.17 2000/03/06 08:18:25 neeri
|
||||
// % Fix sleep, usleep, chdir; new Yield system
|
||||
// %
|
||||
// % Revision 1.16 2000/01/17 01:41:21 neeri
|
||||
// % Fix rename() mangling
|
||||
// %
|
||||
// % Revision 1.15 1999/12/13 03:01:48 neeri
|
||||
// % Another select() fix
|
||||
// %
|
||||
// % Revision 1.14 1999/11/15 07:22:34 neeri
|
||||
// % Safe context setup. Fix sleep checking.
|
||||
// %
|
||||
// % Revision 1.13 1999/09/09 07:21:22 neeri
|
||||
// % Add support for inet_aton
|
||||
// %
|
||||
// % Revision 1.12 1999/08/26 05:45:06 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.11 1999/07/19 06:21:03 neeri
|
||||
// % Add mkdir/rmdir, fix various file manager related bugs
|
||||
// %
|
||||
// % Revision 1.10 1999/07/07 04:17:42 neeri
|
||||
// % Final tweaks for 2.0b3
|
||||
// %
|
||||
// % Revision 1.9 1999/06/28 06:04:59 neeri
|
||||
// % Support interrupted calls
|
||||
// %
|
||||
// % Revision 1.8 1999/05/30 03:09:31 neeri
|
||||
// % Added support for MPW compilers
|
||||
// %
|
||||
// % Revision 1.7 1999/04/29 05:33:18 neeri
|
||||
// % Fix fcntl prototype
|
||||
// %
|
||||
// % Revision 1.6 1999/03/29 09:51:29 neeri
|
||||
// % New configuration system with support for hardcoded configurations.
|
||||
// %
|
||||
// % Revision 1.5 1999/03/17 09:05:11 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// % Revision 1.4 1998/10/25 11:35:19 neeri
|
||||
// % chdir, getcwd, setxxxent
|
||||
// %
|
||||
// % Revision 1.3 1998/10/11 16:45:22 neeri
|
||||
// % Ready to release 2.0a2
|
||||
// %
|
||||
// % Revision 1.2 1998/08/01 21:32:09 neeri
|
||||
// % About ready for 2.0a1
|
||||
// %
|
||||
// % Revision 1.1 1998/01/25 21:02:49 neeri
|
||||
// % Engine implemented, except for signals & scheduling
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{POSIX/Socket Wrappers}
|
||||
//
|
||||
// Now everything is in place to define the POSIX and socket routines
|
||||
// themselves. As opposed to our usual practice, we don't declare the
|
||||
// exported routines here, as they all have been declared in [[unistd.h]]
|
||||
// or [[sys/socket.h]] already. The exceptions are [[remove]] and [[rename]],
|
||||
// which are declared in [[stdio.h]], which we'd rather not include, and
|
||||
// various calls which are not consistently declared.
|
||||
//
|
||||
// <GUSIPOSIX.h>=
|
||||
#ifndef _GUSIPOSIX_
|
||||
#define _GUSIPOSIX_
|
||||
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <utime.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
int remove(const char * path);
|
||||
int rename(const char *oldname, const char *newname);
|
||||
int fgetfileinfo(const char * path, OSType * creator, OSType * type);
|
||||
void fsetfileinfo(const char * path, OSType creator, OSType type);
|
||||
time_t time(time_t * timer);
|
||||
struct tm * localtime(const time_t * timer);
|
||||
struct tm * gmtime(const time_t * timer);
|
||||
time_t mktime(struct tm *timeptr);
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _GUSIPOSIX_ */
|
|
@ -1,37 +0,0 @@
|
|||
// The [[GUSIPPCFactory]] singleton creates [[GUSIPPCSockets]].
|
||||
//
|
||||
// <GUSIPPC.h>=
|
||||
#ifndef _GUSIPPC_
|
||||
#define _GUSIPPC_
|
||||
|
||||
#ifdef GUSI_INTERNAL
|
||||
|
||||
#include "GUSISocket.h"
|
||||
#include "GUSIFactory.h"
|
||||
#include <sys/ppc.h>
|
||||
|
||||
// \section{Definition of [[GUSIPPCFactory]]}
|
||||
//
|
||||
// [[GUSIPPCFactory]] is a singleton subclass of [[GUSISocketFactory]].
|
||||
//
|
||||
// <Definition of class [[GUSIPPCFactory]]>=
|
||||
class GUSIPPCFactory : public GUSISocketFactory {
|
||||
public:
|
||||
static GUSISocketFactory * Instance();
|
||||
virtual GUSISocket * socket(int domain, int type, int protocol);
|
||||
private:
|
||||
GUSIPPCFactory() {}
|
||||
static GUSISocketFactory * sInstance;
|
||||
};
|
||||
|
||||
// <Inline member functions for class [[GUSIPPCFactory]]>=
|
||||
inline GUSISocketFactory * GUSIPPCFactory::Instance()
|
||||
{
|
||||
if (!sInstance)
|
||||
sInstance = new GUSIPPCFactory;
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
#endif /* GUSI_INTERNAL */
|
||||
|
||||
#endif /* _GUSIPPC_ */
|
|
@ -1,30 +0,0 @@
|
|||
// <GUSIPThread.h>=
|
||||
#ifndef _GUSIPThread_
|
||||
#define _GUSIPThread_
|
||||
|
||||
#include "GUSISpecific.h"
|
||||
#include "GUSIContext.h"
|
||||
#include "GUSIContextQueue.h"
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
// <Implementation of Pthread data types>=
|
||||
struct GUSIPThread : public GUSIContext {
|
||||
private:
|
||||
GUSIPThread() : GUSIContext(0) {} // Never called
|
||||
};
|
||||
// <Implementation of Pthread data types>=
|
||||
struct GUSIPThreadKey : public GUSISpecific {
|
||||
GUSIPThreadKey(GUSIPThreadKeyDestructor destructor) : GUSISpecific(destructor) {}
|
||||
};
|
||||
// <Implementation of Pthread data types>=
|
||||
struct GUSIPThreadMutex : public GUSIContextQueue {
|
||||
bool fPolling;
|
||||
|
||||
GUSIPThreadMutex() : fPolling(false) {}
|
||||
};
|
||||
// <Implementation of Pthread data types>=
|
||||
struct GUSIPThreadCond : public GUSIContextQueue {
|
||||
};
|
||||
|
||||
#endif /* _GUSIPThread_ */
|
|
@ -1,88 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSIPipe.nw - Pipes
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.12 2000/05/23 07:18:03 neeri
|
||||
// % Improve formatting
|
||||
// %
|
||||
// % Revision 1.11 2000/03/06 06:09:59 neeri
|
||||
// % Reorganize Yield()
|
||||
// %
|
||||
// % Revision 1.10 1999/11/15 07:20:59 neeri
|
||||
// % Add GUSIwithLocalSockets
|
||||
// %
|
||||
// % Revision 1.9 1999/08/26 05:45:07 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.8 1999/06/28 06:05:00 neeri
|
||||
// % Support interrupted calls
|
||||
// %
|
||||
// % Revision 1.7 1999/05/29 06:26:45 neeri
|
||||
// % Fixed header guards
|
||||
// %
|
||||
// % Revision 1.6 1999/03/17 09:05:12 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// % Revision 1.5 1998/11/22 23:07:00 neeri
|
||||
// % Releasing 2.0a4 in a hurry
|
||||
// %
|
||||
// % Revision 1.4 1998/10/25 11:57:38 neeri
|
||||
// % Ready to release 2.0a3
|
||||
// %
|
||||
// % Revision 1.3 1998/01/25 20:53:57 neeri
|
||||
// % Engine implemented, except for signals & scheduling
|
||||
// %
|
||||
// % Revision 1.2 1996/12/22 19:57:58 neeri
|
||||
// % TCP streams work
|
||||
// %
|
||||
// % Revision 1.1 1996/11/24 12:52:08 neeri
|
||||
// % Added GUSIPipeSockets
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{The GUSI Pipe Socket Class}
|
||||
//
|
||||
// Pipes and socket pairs are implemented with the [[GUSIPipeSocket]] class.
|
||||
// The [[GUSIPipeFactory]] singleton creates pairs of [[GUSIPipeSockets]].
|
||||
//
|
||||
// <GUSIPipe.h>=
|
||||
#ifndef _GUSIPipe_
|
||||
#define _GUSIPipe_
|
||||
|
||||
#ifdef GUSI_INTERNAL
|
||||
|
||||
#include "GUSISocket.h"
|
||||
#include "GUSIFactory.h"
|
||||
|
||||
// \section{Definition of [[GUSIPipeFactory]]}
|
||||
//
|
||||
// [[GUSIPipeFactory]] is a singleton subclass of [[GUSISocketFactory]].
|
||||
//
|
||||
// <Definition of class [[GUSIPipeFactory]]>=
|
||||
class GUSIPipeFactory : public GUSISocketFactory {
|
||||
public:
|
||||
static GUSISocketFactory * Instance();
|
||||
virtual GUSISocket * socket(int domain, int type, int protocol);
|
||||
virtual int socketpair(int domain, int type, int protocol, GUSISocket * s[2]);
|
||||
private:
|
||||
GUSIPipeFactory() {}
|
||||
static GUSISocketFactory * sInstance;
|
||||
};
|
||||
|
||||
// <Inline member functions for class [[GUSIPipeFactory]]>=
|
||||
inline GUSISocketFactory * GUSIPipeFactory::Instance()
|
||||
{
|
||||
if (!sInstance)
|
||||
sInstance = new GUSIPipeFactory;
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
#endif /* GUSI_INTERNAL */
|
||||
|
||||
#endif /* _GUSIPipe_ */
|
|
@ -1,48 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSISIOUX.nw - SIOUX Support
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.8 2000/05/23 07:18:03 neeri
|
||||
// % Improve formatting
|
||||
// %
|
||||
// % Revision 1.7 2000/03/06 06:03:29 neeri
|
||||
// % Check device families for file paths
|
||||
// %
|
||||
// % Revision 1.6 1999/08/26 05:45:08 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.5 1999/06/08 04:31:30 neeri
|
||||
// % Getting ready for 2.0b2
|
||||
// %
|
||||
// % Revision 1.4 1999/05/29 06:26:45 neeri
|
||||
// % Fixed header guards
|
||||
// %
|
||||
// % Revision 1.3 1999/03/17 09:05:12 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// % Revision 1.2 1998/11/22 23:07:01 neeri
|
||||
// % Releasing 2.0a4 in a hurry
|
||||
// %
|
||||
// % Revision 1.1 1998/10/25 11:57:39 neeri
|
||||
// % Ready to release 2.0a3
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{SIOUX Support}
|
||||
//
|
||||
// To combine GUSI with SIOUX, terminal I/O needs to interface with the SIOUX
|
||||
// event handling.
|
||||
//
|
||||
// SIOUX support is installed implicitly through [[GUSISetupConsoleDescriptors]]
|
||||
//
|
||||
// <GUSISIOUX.h>=
|
||||
#ifndef _GUSISIOUX_
|
||||
#define _GUSISIOUX_
|
||||
|
||||
#endif /* _GUSISIOUX_ */
|
|
@ -1,27 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSISIOW.nw - SIOW Interface
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.2 1999/08/26 05:45:08 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.1 1999/07/19 06:17:08 neeri
|
||||
// % Add SIOW support
|
||||
// %
|
||||
//
|
||||
// \chapter{SIOW Support}
|
||||
//
|
||||
// SIOW support is based on MPW support, adding a few event hooks so update and activate events
|
||||
// get handled during blocking calls. SIOW support is installed implecitly through [[GUSIDefaultSetupConsole]].
|
||||
//
|
||||
// <GUSISIOW.h>=
|
||||
#ifndef _GUSISIOW_
|
||||
#define _GUSISIOW_
|
||||
|
||||
#endif /* _GUSISIOW_ */
|
|
@ -1,149 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSISignal.nw - Signal engine
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.7 2000/10/16 04:08:51 neeri
|
||||
// % Add binary compatibility for CW SIGINT
|
||||
// %
|
||||
// % Revision 1.6 2000/05/23 07:18:03 neeri
|
||||
// % Improve formatting
|
||||
// %
|
||||
// % Revision 1.5 2000/03/15 07:22:07 neeri
|
||||
// % Enforce alignment choices
|
||||
// %
|
||||
// % Revision 1.4 1999/12/13 03:07:25 neeri
|
||||
// % Releasing 2.0.2
|
||||
// %
|
||||
// % Revision 1.3 1999/11/15 07:20:18 neeri
|
||||
// % Safe context setup
|
||||
// %
|
||||
// % Revision 1.2 1999/08/26 05:45:09 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.1 1999/06/30 07:42:07 neeri
|
||||
// % Getting ready to release 2.0b3
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{Signal support}
|
||||
//
|
||||
// We support signals in the half assed way characteristic for GUSI's approach to
|
||||
// asynchronous issues: Delivery is very much synchronous, basically within [[Yield]]
|
||||
// calls. Signal handling behavior is encapsulated in the classes [[GUSISigContext]] and
|
||||
// [[GUSISigProcess]] whose instances are manufactured by a [[GUSISigFactory]].
|
||||
//
|
||||
// <GUSISignal.h>=
|
||||
#ifndef _GUSISIGNAL_
|
||||
#define _GUSISIGNAL_
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#ifdef GUSI_SOURCE
|
||||
|
||||
#include <ConditionalMacros.h>
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=native
|
||||
#endif
|
||||
|
||||
// \section{Definition of the signal handling engine}
|
||||
//
|
||||
// A [[GUSISigProcess]] contains the per-process signal state. [[GetAction]] and [[SetAction]] manipulate the
|
||||
// action associated with a signal, [[Pending]] returns the set of pending signals, [[Post]] marks a signal
|
||||
// as pending (but possibly blocked), and [[Raise]] executes a signal (which we have determined is not
|
||||
// blocked).
|
||||
//
|
||||
// <Definition of class [[GUSISigProcess]]>=
|
||||
class GUSISigContext;
|
||||
|
||||
class GUSISigProcess {
|
||||
public:
|
||||
virtual struct sigaction & GetAction(int sig);
|
||||
virtual int SetAction(int sig, const struct sigaction & act);
|
||||
virtual sigset_t Pending() const;
|
||||
virtual void ClearPending(sigset_t clear);
|
||||
virtual void Post(int sig);
|
||||
virtual bool Raise(int sig, GUSISigContext * context);
|
||||
|
||||
virtual ~GUSISigProcess();
|
||||
protected:
|
||||
// [[GUSISigProcess]] stores the signal handlers and the set of signals pending against the process.
|
||||
//
|
||||
// <Privatissima of [[GUSISigProcess]]>=
|
||||
sigset_t fPending;
|
||||
struct sigaction fAction[NSIG-1];
|
||||
// Some actions can't be caught and/or ignored. [[CantCatch]] and [[CantIgnore]] report those.
|
||||
//
|
||||
// <Privatissima of [[GUSISigProcess]]>=
|
||||
virtual bool CantCatch(int sig);
|
||||
virtual bool CantIgnore(int sig);
|
||||
// The default behavior for many signals is to abort the process.
|
||||
//
|
||||
// <Privatissima of [[GUSISigProcess]]>=
|
||||
virtual bool DefaultAction(int sig, const struct sigaction & act);
|
||||
|
||||
friend class GUSISigFactory;
|
||||
GUSISigProcess();
|
||||
};
|
||||
// A [[GUSISigContext]] contains the per-thread signal state, primarily blocking info. To support
|
||||
// [[pthread_kill]], we have out own set of pending signals. [[GetBlocked]] and [[SetBlocked]] manipulate
|
||||
// the set of blocking signals, [[Pending]] returns the set of pending signals, [[Post]] marks a
|
||||
// signal as pending (but possibly blocked), and [[Raise]] executes all eligible signals.
|
||||
//
|
||||
// <Definition of class [[GUSISigContext]]>=
|
||||
class GUSISigContext {
|
||||
public:
|
||||
virtual sigset_t GetBlocked() const;
|
||||
virtual void SetBlocked(sigset_t sigs);
|
||||
virtual sigset_t Pending() const;
|
||||
virtual sigset_t Pending(GUSISigProcess * proc) const;
|
||||
virtual void ClearPending(sigset_t clear);
|
||||
virtual void Post(int sig);
|
||||
virtual sigset_t Ready(GUSISigProcess * proc);
|
||||
virtual bool Raise(GUSISigProcess * proc, bool allSigs = false);
|
||||
|
||||
virtual ~GUSISigContext();
|
||||
protected:
|
||||
// [[GUSISigContext]] mainly deals with a set of blocked signals, which it inherits from its parent.
|
||||
//
|
||||
// <Privatissima of [[GUSISigContext]]>=
|
||||
sigset_t fPending;
|
||||
sigset_t fBlocked;
|
||||
// Many signals cannot be blocked. [[CantBlock]] defines those.
|
||||
//
|
||||
// <Privatissima of [[GUSISigContext]]>=
|
||||
virtual sigset_t CantBlock();
|
||||
|
||||
friend class GUSISigFactory;
|
||||
GUSISigContext(const GUSISigContext * parent);
|
||||
};
|
||||
// The [[GUSISigFactory]] singleton creates the above two classes, allowing a future extension to
|
||||
// handle more signals.
|
||||
//
|
||||
// <Definition of class [[GUSISigFactory]]>=
|
||||
class GUSISigFactory {
|
||||
public:
|
||||
virtual GUSISigProcess * CreateSigProcess();
|
||||
virtual GUSISigContext * CreateSigContext(const GUSISigContext * parent);
|
||||
|
||||
virtual ~GUSISigFactory();
|
||||
|
||||
static GUSISigFactory * Instance();
|
||||
static void SetInstance(GUSISigFactory * instance);
|
||||
protected:
|
||||
GUSISigFactory() {}
|
||||
};
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=reset
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _GUSISIGNAL_ */
|
|
@ -1,362 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSISocket.nw - The socket class
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:14 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.18 2000/10/16 04:34:23 neeri
|
||||
// % Releasing 2.1.2
|
||||
// %
|
||||
// % Revision 1.17 2000/05/23 07:19:34 neeri
|
||||
// % Improve formatting, add close queue
|
||||
// %
|
||||
// % Revision 1.16 2000/03/15 07:20:53 neeri
|
||||
// % Add GUSISocket::AddContextInScope
|
||||
// %
|
||||
// % Revision 1.15 1999/10/15 02:48:51 neeri
|
||||
// % Make disconnects orderly
|
||||
// %
|
||||
// % Revision 1.14 1999/09/26 03:59:26 neeri
|
||||
// % Releasing 2.0fc1
|
||||
// %
|
||||
// % Revision 1.13 1999/08/26 05:45:09 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.12 1999/06/08 04:31:31 neeri
|
||||
// % Getting ready for 2.0b2
|
||||
// %
|
||||
// % Revision 1.11 1999/05/29 06:26:45 neeri
|
||||
// % Fixed header guards
|
||||
// %
|
||||
// % Revision 1.10 1999/04/29 05:33:18 neeri
|
||||
// % Fix fcntl prototype
|
||||
// %
|
||||
// % Revision 1.9 1999/03/17 09:05:13 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// % Revision 1.8 1998/11/22 23:07:01 neeri
|
||||
// % Releasing 2.0a4 in a hurry
|
||||
// %
|
||||
// % Revision 1.7 1998/10/11 16:45:23 neeri
|
||||
// % Ready to release 2.0a2
|
||||
// %
|
||||
// % Revision 1.6 1998/08/01 21:29:53 neeri
|
||||
// % Use context queues
|
||||
// %
|
||||
// % Revision 1.5 1998/01/25 20:53:58 neeri
|
||||
// % Engine implemented, except for signals & scheduling
|
||||
// %
|
||||
// % Revision 1.4 1997/11/13 21:12:12 neeri
|
||||
// % Fall 1997
|
||||
// %
|
||||
// % Revision 1.3 1996/11/24 13:00:28 neeri
|
||||
// % Fix comment leaders
|
||||
// %
|
||||
// % Revision 1.2 1996/11/24 12:52:09 neeri
|
||||
// % Added GUSIPipeSockets
|
||||
// %
|
||||
// % Revision 1.1.1.1 1996/11/03 02:43:32 neeri
|
||||
// % Imported into CVS
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{The GUSI Socket Class}
|
||||
//
|
||||
// GUSI is constructed around the [[GUSISocket]] class. This class is
|
||||
// mostly an abstract superclass, but all virtual procedures are implemented
|
||||
// to return sensible error codes.
|
||||
//
|
||||
// <GUSISocket.h>=
|
||||
#ifndef _GUSISocket_
|
||||
#define _GUSISocket_
|
||||
|
||||
#ifdef GUSI_SOURCE
|
||||
|
||||
#include "GUSIBasics.h"
|
||||
#include "GUSIContext.h"
|
||||
#include "GUSIContextQueue.h"
|
||||
#include "GUSIBuffer.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <ConditionalMacros.h>
|
||||
#include <LowMem.h>
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=native
|
||||
#endif
|
||||
|
||||
// \section{Definition of [[GUSISocket]]}
|
||||
//
|
||||
// [[GUSISocket]] consists of a few maintenance functions and the socket operations.
|
||||
// Each operation consists to a POSIX/BSD function with the file descriptor operand
|
||||
// left out.
|
||||
//
|
||||
// <Definition of class [[GUSISocket]]>=
|
||||
class GUSISocket {
|
||||
// Since a single [[GUSISocket]] may (through [[dup]]) be installed multiply
|
||||
// in a descriptor table or even in multiple descriptor tables, [[GUSISocket]]s
|
||||
// are not destroyed directly, but by manipulating a reference count. As soon
|
||||
// as the reference count hits zero, the destructor (which, of course, should
|
||||
// probably be overridden) is called.
|
||||
//
|
||||
// Since destructors cannot call virtual functions, we call [[close]] which
|
||||
// eventually calls the destructor. Some socket types can take quite long to close
|
||||
// under unfavorable circumstances. To speed up the process, we have the option of
|
||||
// queueing the socket up and regularly having [[Close]] called on it.
|
||||
//
|
||||
// <Reference counting for [[GUSISocket]]>=
|
||||
public:
|
||||
void AddReference();
|
||||
void RemoveReference();
|
||||
|
||||
virtual void close();
|
||||
void CheckClose(UInt32 now = LMGetTicks());
|
||||
protected:
|
||||
GUSISocket();
|
||||
virtual ~GUSISocket();
|
||||
virtual bool Close(UInt32 now = LMGetTicks());
|
||||
private:
|
||||
u_long fRefCount;
|
||||
// [[GUSIContext]]s are defined in {\tt GUSIBasics}. A context references all
|
||||
// information you need in a completion procedure: The contents of [[A5]],
|
||||
// the process ID, and thread information. [[Wakeup]] wakes up the threads
|
||||
// and/or processes associated with the socket and is guaranteed to work even
|
||||
// at interrupt level. [[AddContext]] adds another context. [[RemoveContext]]
|
||||
// indicates that this context no longer should be woken up when something happens.
|
||||
// To keep a context added inside a scope, declare an automatic object of class
|
||||
// [[AddContextInScope]].
|
||||
//
|
||||
// <Context links for [[GUSISocket]]>=
|
||||
public:
|
||||
void Wakeup();
|
||||
void AddContext(GUSIContext * context = nil);
|
||||
void RemoveContext(GUSIContext * context = nil);
|
||||
|
||||
class AddContextInScope {
|
||||
public:
|
||||
AddContextInScope(GUSISocket * sock, GUSIContext * context = nil)
|
||||
: fSocket(sock), fContext(context)
|
||||
{ fSocket->AddContext(fContext); }
|
||||
~AddContextInScope() { fSocket->RemoveContext(fContext); }
|
||||
private:
|
||||
GUSISocket * fSocket;
|
||||
GUSIContext * fContext;
|
||||
};
|
||||
private:
|
||||
GUSIContextQueue fContexts;
|
||||
// There may be various reasons to keep sockets in queue. Currently the
|
||||
// only reason is to queue up dying sockets.
|
||||
//
|
||||
// <Queue management for [[GUSISocket]]>=
|
||||
public:
|
||||
void Enqueue(GUSISocket ** queue);
|
||||
void Dequeue();
|
||||
private:
|
||||
GUSISocket ** fQueue;
|
||||
GUSISocket * fNextSocket;
|
||||
GUSISocket * fPrevSocket;
|
||||
// Both read and write calls on sockets come in five different variants:
|
||||
//
|
||||
// \begin{enumerate}
|
||||
// \item [[read]] and [[write]]
|
||||
// \item [[recv]] and [[send]]
|
||||
// \item [[readv]] and [[writev]]
|
||||
// \item [[recvfrom]] and [[sendto]]
|
||||
// \item [[recvmsg]] and [[sendmsg]]
|
||||
// \end{enumerate}
|
||||
//
|
||||
// GUSI initially maps variants 3 and 5 of these calls to the [[recvmsg]] and
|
||||
// [[sendmsg]] member functions, variants 2 and 4 to the [[recvfrom]] and
|
||||
// [[sendto]] member functions, and variant 1 to the [[read]] and
|
||||
// [[write]] member functions.
|
||||
//
|
||||
// The simpler member functions can always be translated into the complex member
|
||||
// functions, and under some circumstances, the opposite is also possible.
|
||||
// To avoid translation loops, the translation routines (i.e., the default
|
||||
// implementation of [[GUSISocket::read]] and [[GUSISocket::recvmsg]]
|
||||
// check for the availablility of the other function by calling [[Supports]].
|
||||
// This member function must be overridden for any reasonable socket class.
|
||||
//
|
||||
// <Configuration options for [[GUSISocket]]>=
|
||||
protected:
|
||||
enum ConfigOption {
|
||||
kSimpleCalls, // [[read]], [[write]]
|
||||
kSocketCalls, // [[recvfrom]], [[sendto]]
|
||||
kMsgCalls // [[recvmsg]], [[sendmsg]]
|
||||
};
|
||||
virtual bool Supports(ConfigOption config);
|
||||
public:
|
||||
// Most sockets have names, which to [[GUSISocket]] are just opaque blocks of
|
||||
// memory. A name for a socket is established (before the socket is actually
|
||||
// used, of course) through [[bind]]. The name may be queried with
|
||||
// [[getsockname]] and once the socket is connected, the name of the peer
|
||||
// endpoint may be queried with [[getpeername]].
|
||||
//
|
||||
// <Socket name management for [[GUSISocket]]>=
|
||||
virtual int bind(void * name, socklen_t namelen);
|
||||
virtual int getsockname(void * name, socklen_t * namelen);
|
||||
virtual int getpeername(void * name, socklen_t * namelen);
|
||||
// Sockets follow either a virtual circuit model where all data is exchanged
|
||||
// with the same peer throughout the lifetime of the connection, or a datagram
|
||||
// model where potentially every message is exchanged with a different peer.
|
||||
//
|
||||
// The vast majority of protocols follow the virtual circuit model. The server
|
||||
// end, typically after calling [[bind]] to attach the socket to a well known
|
||||
// address, calls [[listen]] to establish its willingness to accept connections.
|
||||
// [[listen]] takes a queue length parameter, which however is ignored for many
|
||||
// types of sockets.
|
||||
//
|
||||
// Incoming connections are then accepted by calling [[accept]]. When [[accept]]
|
||||
// is successful, it always returns a new [[GUSISocket]], while the original socket
|
||||
// remains available for further connections. To avoid blocking on [[accept]], you may poll for connections with an
|
||||
// [[accept()] call in nonblocking mode or query the result of [[select]] whether
|
||||
// the socket is ready for reading.
|
||||
//
|
||||
// The client end in the virtual circuit model connects itself to the well known
|
||||
// address by calling [[connect]]. To avoid blocking on [[connect]], you may
|
||||
// call it in nonblocking mode and then query the result of [[select]] whether
|
||||
// the socket is ready for writing.
|
||||
//
|
||||
// In the datagram model, you don't need to establish connections. You may call
|
||||
// [[connect]] anyway to temporarily establish a virtual circuit.
|
||||
//
|
||||
// <Connection establishment for [[GUSISocket]]>=
|
||||
virtual int listen(int qlen);
|
||||
virtual GUSISocket * accept(void * address, socklen_t * addrlen);
|
||||
virtual int connect(void * address, socklen_t addrlen);
|
||||
// As mentioned before, there are three variants each for reading and writing.
|
||||
// The socket variants provide a means to pass a peer address for the datagram
|
||||
// model, while the msg variants also provides fields for passing access rights,
|
||||
// which is, however not currently supported in GUSI. As syntactic sugar, the more
|
||||
// traditional flavors with [[buffer]]/[[length]] buffers are also supported.
|
||||
//
|
||||
// <Sending and receiving data for [[GUSISocket]]>=
|
||||
virtual ssize_t read(const GUSIScatterer & buffer);
|
||||
virtual ssize_t write(const GUSIGatherer & buffer);
|
||||
virtual ssize_t recvfrom(
|
||||
const GUSIScatterer & buffer, int flags, void * from, socklen_t * fromlen);
|
||||
virtual ssize_t sendto(
|
||||
const GUSIGatherer & buffer, int flags, const void * to, socklen_t tolen);
|
||||
virtual ssize_t recvmsg(msghdr * msg, int flags);
|
||||
virtual ssize_t sendmsg(const msghdr * msg, int flags);
|
||||
|
||||
ssize_t read(void * buffer, size_t length);
|
||||
ssize_t write(const void * buffer, size_t length);
|
||||
ssize_t recvfrom(
|
||||
void * buffer, size_t length, int flags, void * from, socklen_t * fromlen);
|
||||
ssize_t sendto(
|
||||
const void * buffer, size_t length, int flags, const void * to, socklen_t tolen);
|
||||
// A multitude of parameters can be manipulated for a [[GUSISocket]] through
|
||||
// the socket oriented calls [[getsockopt]], [[setsockopt]], the file oriented
|
||||
// call [[fcntl]], and the device oriented call [[ioctl]].
|
||||
//
|
||||
// [[isatty]] returns whether the socket should be considered an interactive
|
||||
// console.
|
||||
//
|
||||
// <Maintaining properties for [[GUSISocket]]>=
|
||||
virtual int getsockopt(int level, int optname, void *optval, socklen_t * optlen);
|
||||
virtual int setsockopt(int level, int optname, void *optval, socklen_t optlen);
|
||||
virtual int fcntl(int cmd, va_list arg);
|
||||
virtual int ioctl(unsigned int request, va_list arg);
|
||||
virtual int isatty();
|
||||
// Three of the operations make sense primarily for files, and most other socket
|
||||
// types accept the default implementations. [[fstat]] returns information about
|
||||
// an open file, [[lseek]] repositions the read/write pointer, and [[ftruncate]]
|
||||
// cuts off an open file at a certain point.
|
||||
//
|
||||
// <File oriented operations for [[GUSISocket]]>=
|
||||
virtual int fstat(struct stat * buf);
|
||||
virtual off_t lseek(off_t offset, int whence);
|
||||
virtual int ftruncate(off_t offset);
|
||||
// [[select]] polls or waits for one of a group of [[GUSISocket]] to become
|
||||
// ready for reading, writing, or for an exceptional condition to occur.
|
||||
// First, [[pre_select]] is called once for all [[GUSISocket]]s in the group.
|
||||
// It returns [[true]] is the socket will wake up as soon as one of the events
|
||||
// occurs and [[false]] if GUSI needs to poll.
|
||||
// Next, [[select]] is called for all [[GUSISocket]]s once or multiple times,
|
||||
// until a condition becomes true or the call times out. Finally, [[post_select]]
|
||||
// is called for all members of the group.
|
||||
//
|
||||
// <Multiplexing for [[GUSISocket]]>=
|
||||
virtual bool pre_select(bool wantRead, bool wantWrite, bool wantExcept);
|
||||
virtual bool select(bool * canRead, bool * canWrite, bool * exception);
|
||||
virtual void post_select(bool wantRead, bool wantWrite, bool wantExcept);
|
||||
// A socket connection is usually full duplex. By calling [[shutdown(1)]], you
|
||||
// indicate that you won't write any more data on this socket. The values 0 (no
|
||||
// more reads) and 2 (no more read/write) are used less frequently.
|
||||
//
|
||||
// <Miscellaneous operations for [[GUSISocket]]>=
|
||||
virtual int shutdown(int how);
|
||||
// Some socket types do not write out data immediately. Calling [[fsync]] guarantees
|
||||
// that all data is written.
|
||||
//
|
||||
// <Miscellaneous operations for [[GUSISocket]]>=
|
||||
virtual int fsync();
|
||||
};
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=reset
|
||||
#endif
|
||||
|
||||
// \section{Implementation of [[GUSISocket]]}
|
||||
//
|
||||
// \subsection{General socket management}
|
||||
//
|
||||
//
|
||||
// <Inline member functions for class [[GUSISocket]]>=
|
||||
inline void GUSISocket::AddReference()
|
||||
{
|
||||
++fRefCount;
|
||||
}
|
||||
|
||||
inline void GUSISocket::RemoveReference()
|
||||
{
|
||||
if (!--fRefCount)
|
||||
close();
|
||||
}
|
||||
|
||||
// \subsection{Context management}
|
||||
//
|
||||
//
|
||||
// <Inline member functions for class [[GUSISocket]]>=
|
||||
inline void GUSISocket::Wakeup()
|
||||
{
|
||||
fContexts.Wakeup();
|
||||
}
|
||||
|
||||
// The traditional flavors of the I/O calls are translated to the scatterer/gatherer
|
||||
// variants.
|
||||
//
|
||||
// <Inline member functions for class [[GUSISocket]]>=
|
||||
inline ssize_t GUSISocket::read(void * buffer, size_t length)
|
||||
{
|
||||
return read(GUSIScatterer(buffer, length));
|
||||
}
|
||||
|
||||
inline ssize_t GUSISocket::write(const void * buffer, size_t length)
|
||||
{
|
||||
return write(GUSIGatherer(buffer, length));
|
||||
}
|
||||
|
||||
inline ssize_t GUSISocket::recvfrom(
|
||||
void * buffer, size_t length, int flags, void * from, socklen_t * fromlen)
|
||||
{
|
||||
return recvfrom(GUSIScatterer(buffer, length), flags, from, fromlen);
|
||||
}
|
||||
|
||||
inline ssize_t GUSISocket::sendto(
|
||||
const void * buffer, size_t length, int flags, const void * to, socklen_t tolen)
|
||||
{
|
||||
return sendto(GUSIGatherer(buffer, length), flags, to, tolen);
|
||||
}
|
||||
|
||||
#endif /* GUSI_SOURCE */
|
||||
|
||||
#endif /* _GUSISocket_ */
|
|
@ -1,360 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSISocketMixins.nw - Useful building blocks
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:14 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.11 2000/10/16 04:10:12 neeri
|
||||
// % Add GUSISMProcess
|
||||
// %
|
||||
// % Revision 1.10 2000/05/23 07:24:58 neeri
|
||||
// % Improve formatting
|
||||
// %
|
||||
// % Revision 1.9 1999/08/26 05:45:09 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.8 1999/08/02 07:02:46 neeri
|
||||
// % Support for asynchronous errors and other socket options
|
||||
// %
|
||||
// % Revision 1.7 1999/05/29 06:26:45 neeri
|
||||
// % Fixed header guards
|
||||
// %
|
||||
// % Revision 1.6 1999/04/29 05:33:18 neeri
|
||||
// % Fix fcntl prototype
|
||||
// %
|
||||
// % Revision 1.5 1999/03/17 09:05:13 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// % Revision 1.4 1998/10/11 16:45:24 neeri
|
||||
// % Ready to release 2.0a2
|
||||
// %
|
||||
// % Revision 1.3 1998/01/25 20:53:59 neeri
|
||||
// % Engine implemented, except for signals & scheduling
|
||||
// %
|
||||
// % Revision 1.2 1997/11/13 21:12:13 neeri
|
||||
// % Fall 1997
|
||||
// %
|
||||
// % Revision 1.1 1996/12/16 02:12:42 neeri
|
||||
// % TCP Sockets sort of work
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{Mixin Classes for Sockets}
|
||||
//
|
||||
// This section contains some building block classes for sockets:
|
||||
//
|
||||
// \begin{itemize}
|
||||
// \item [[GUSISMBlocking]] implements the blocking/nonblocking flag.
|
||||
// \item [[GUSISMState]] implements a state variable.
|
||||
// \item [[GUSISMInputBuffer]] provides a [[GUSIBuffer]] for input.
|
||||
// \item [[GUSISMOutputBuffer]] provides a [[GUSIBuffer]] for output.
|
||||
// \item [[GUSISMAsyncError]] provides storage for asynchronous errors.
|
||||
// \item [[GUSISMProcess]] maintains a link to the process instance.
|
||||
// \end{itemize}
|
||||
//
|
||||
//
|
||||
// <GUSISocketMixins.h>=
|
||||
#ifndef _GUSISocketMixins_
|
||||
#define _GUSISocketMixins_
|
||||
|
||||
#ifdef GUSI_INTERNAL
|
||||
|
||||
#include "GUSISocket.h"
|
||||
#include "GUSIBuffer.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
// \section{Definition of [[GUSISocketMixins]]}
|
||||
//
|
||||
// [[GUSISMBlocking]] implements the [[fBlocking]] flags and the [[DoIoctl]] and
|
||||
// [[DoFcntl]] variants to manipulate it. These two functions work like their
|
||||
// [[GUSISocket]] member function counterparts, but handle the return value
|
||||
// differently: The POSIX function result is stored in [[*result]], while the
|
||||
// return value indicates whether the request was handled.
|
||||
//
|
||||
// <Definition of class [[GUSISMBlocking]]>=
|
||||
class GUSISMBlocking {
|
||||
public:
|
||||
GUSISMBlocking();
|
||||
bool fBlocking;
|
||||
bool DoFcntl(int * result, int cmd, va_list arg);
|
||||
bool DoIoctl(int * result, unsigned int request, va_list arg);
|
||||
};
|
||||
// [[GUSISMState]] captures the state of a socket over its lifetime. It starts out
|
||||
// as [[Unbound]]. [[bind]] will put it into [[Unconnected]] state, though few
|
||||
// socket classes care about this distinction. [[listen]] will put it into
|
||||
// [[Listening]] state. [[accept]] starts a [[Connected]] new socket.
|
||||
// [[connect]] puts an [[Unconnected]] socket into [[Connecting]] state from
|
||||
// where it emerges [[Connected]]. [[fReadShutdown]] and [[fWriteShutdown]] record
|
||||
// shutdown promises.
|
||||
//
|
||||
// <Definition of class [[GUSISMState]]>=
|
||||
class GUSISMState {
|
||||
public:
|
||||
enum State {
|
||||
Unbound,
|
||||
Unconnected,
|
||||
Listening,
|
||||
Connecting,
|
||||
Connected,
|
||||
Closing
|
||||
};
|
||||
GUSISMState();
|
||||
State fState;
|
||||
bool fReadShutdown;
|
||||
bool fWriteShutdown;
|
||||
void Shutdown(int how);
|
||||
};
|
||||
// [[GUSISMInputBuffer]] defines the input buffer and some socket options that go
|
||||
// with it. [[DoGetSockOpt]] and [[DoSetSockOpt]] work the same way as
|
||||
// [[DoFcntl]] and [[DoIoctl]] above.
|
||||
//
|
||||
// <Definition of class [[GUSISMInputBuffer]]>=
|
||||
class GUSISMInputBuffer {
|
||||
public:
|
||||
GUSIRingBuffer fInputBuffer;
|
||||
GUSISMInputBuffer();
|
||||
bool DoGetSockOpt(
|
||||
int * result, int level, int optname,
|
||||
void *optval, socklen_t * optlen);
|
||||
bool DoSetSockOpt(
|
||||
int * result, int level, int optname,
|
||||
void *optval, socklen_t optlen);
|
||||
bool DoIoctl(int * result, unsigned int request, va_list arg);
|
||||
};
|
||||
// [[GUSISMOutputBuffer]] defines the output buffer and some socket options that go
|
||||
// with it.
|
||||
//
|
||||
// <Definition of class [[GUSISMOutputBuffer]]>=
|
||||
class GUSISMOutputBuffer {
|
||||
public:
|
||||
GUSIRingBuffer fOutputBuffer;
|
||||
GUSISMOutputBuffer();
|
||||
bool DoGetSockOpt(
|
||||
int * result, int level, int optname,
|
||||
void *optval, socklen_t * optlen);
|
||||
bool DoSetSockOpt(
|
||||
int * result, int level, int optname,
|
||||
void *optval, socklen_t optlen);
|
||||
};
|
||||
// [[GUSISMAsyncError]] stores asynchronous errors and makes them available via
|
||||
// [[getsockopt]]. [[GetAsyncError]] returns the error and resets the stored value.
|
||||
//
|
||||
// <Definition of class [[GUSISMAsyncError]]>=
|
||||
class GUSISMAsyncError {
|
||||
public:
|
||||
GUSISMAsyncError();
|
||||
int fAsyncError;
|
||||
int SetAsyncPosixError(int error);
|
||||
int SetAsyncMacError(OSErr error);
|
||||
int GetAsyncError();
|
||||
bool DoGetSockOpt(
|
||||
int * result, int level, int optname,
|
||||
void *optval, socklen_t * optlen);
|
||||
};
|
||||
// [[GUSISMProcess]] stores a link to the global [[GUSIProcess]] instance, which is useful for completion routines.
|
||||
//
|
||||
// <Definition of class [[GUSISMProcess]]>=
|
||||
class GUSISMProcess {
|
||||
public:
|
||||
GUSISMProcess();
|
||||
|
||||
GUSIProcess * Process();
|
||||
private:
|
||||
GUSIProcess * fProcess;
|
||||
};
|
||||
|
||||
// \section{Implementation of [[GUSISocketMixins]]}
|
||||
//
|
||||
// Because all the member functions are simple and called in few places, it
|
||||
// makes sense to inline them.
|
||||
//
|
||||
// All sockets start out blocking.
|
||||
//
|
||||
// <Inline member functions for class [[GUSISMBlocking]]>=
|
||||
inline GUSISMBlocking::GUSISMBlocking() : fBlocking(true) {}
|
||||
// For historical reasons, there is both an [[ioctl]] and a [[fcntl]] interface
|
||||
// to the blocking flag.
|
||||
//
|
||||
// <Inline member functions for class [[GUSISMBlocking]]>=
|
||||
inline bool GUSISMBlocking::DoFcntl(int * result, int cmd, va_list arg)
|
||||
{
|
||||
switch(cmd) {
|
||||
case F_GETFL :
|
||||
return (*result = fBlocking ? 0: FNDELAY), true;
|
||||
case F_SETFL :
|
||||
fBlocking = !(va_arg(arg, int) & FNDELAY);
|
||||
|
||||
return (*result = 0), true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
inline bool GUSISMBlocking::DoIoctl(int * result, unsigned int request, va_list arg)
|
||||
{
|
||||
if (request == FIONBIO) {
|
||||
fBlocking = !*va_arg(arg, int *);
|
||||
return (*result = 0), true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// Sockets start out as unconnected.
|
||||
//
|
||||
// <Inline member functions for class [[GUSISMState]]>=
|
||||
inline GUSISMState::GUSISMState() :
|
||||
fState(Unbound), fReadShutdown(false), fWriteShutdown(false) {}
|
||||
// <Inline member functions for class [[GUSISMState]]>=
|
||||
inline void GUSISMState::Shutdown(int how)
|
||||
{
|
||||
if (!(how & 1))
|
||||
fReadShutdown = true;
|
||||
if (how > 0)
|
||||
fWriteShutdown = true;
|
||||
}
|
||||
// Buffers initially are 8K.
|
||||
//
|
||||
// <Inline member functions for class [[GUSISMInputBuffer]]>=
|
||||
inline GUSISMInputBuffer::GUSISMInputBuffer() : fInputBuffer(8192) {}
|
||||
// [[getsockopt]] is used to obtain the buffer size.
|
||||
//
|
||||
// <Inline member functions for class [[GUSISMInputBuffer]]>=
|
||||
inline bool GUSISMInputBuffer::DoGetSockOpt(
|
||||
int * result, int level, int optname,
|
||||
void *optval, socklen_t *)
|
||||
{
|
||||
if (level == SOL_SOCKET && optname == SO_RCVBUF) {
|
||||
*(int *)optval = (int)fInputBuffer.Size();
|
||||
|
||||
return (*result = 0), true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// [[setsockopt]] modifies the buffer size.
|
||||
//
|
||||
// <Inline member functions for class [[GUSISMInputBuffer]]>=
|
||||
inline bool GUSISMInputBuffer::DoSetSockOpt(
|
||||
int * result, int level, int optname,
|
||||
void *optval, socklen_t)
|
||||
{
|
||||
if (level == SOL_SOCKET && optname == SO_RCVBUF) {
|
||||
fInputBuffer.SwitchBuffer(*(int *)optval);
|
||||
|
||||
return (*result = 0), true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// [[ioctl]] returns the number of available bytes.
|
||||
//
|
||||
// <Inline member functions for class [[GUSISMInputBuffer]]>=
|
||||
inline bool GUSISMInputBuffer::DoIoctl(int * result, unsigned int request, va_list arg)
|
||||
{
|
||||
if (request == FIONREAD) {
|
||||
*va_arg(arg, long *) = fInputBuffer.Valid();
|
||||
return (*result = 0), true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// [[GUSISMOutputBuffer]] works identically to the input buffer.
|
||||
//
|
||||
// <Inline member functions for class [[GUSISMOutputBuffer]]>=
|
||||
inline GUSISMOutputBuffer::GUSISMOutputBuffer() : fOutputBuffer(8192) {}
|
||||
// [[getsockopt]] is used to obtain the buffer size.
|
||||
//
|
||||
// <Inline member functions for class [[GUSISMOutputBuffer]]>=
|
||||
inline bool GUSISMOutputBuffer::DoGetSockOpt(
|
||||
int * result, int level, int optname,
|
||||
void *optval, socklen_t *)
|
||||
{
|
||||
if (level == SOL_SOCKET && optname == SO_SNDBUF) {
|
||||
*(int *)optval = (int)fOutputBuffer.Size();
|
||||
|
||||
return (*result = 0), true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// [[setsockopt]] is modifies the buffer size.
|
||||
//
|
||||
// <Inline member functions for class [[GUSISMOutputBuffer]]>=
|
||||
inline bool GUSISMOutputBuffer::DoSetSockOpt(
|
||||
int * result, int level, int optname,
|
||||
void *optval, socklen_t)
|
||||
{
|
||||
if (level == SOL_SOCKET && optname == SO_SNDBUF) {
|
||||
fOutputBuffer.SwitchBuffer(*(int *)optval);
|
||||
|
||||
return (*result = 0), true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// <Inline member functions for class [[GUSISMAsyncError]]>=
|
||||
inline GUSISMAsyncError::GUSISMAsyncError()
|
||||
: fAsyncError(0)
|
||||
{
|
||||
}
|
||||
// The central member functions of [[GUSISMAsyncError]] are [[SetAsyncXXXError]] and
|
||||
// [[GetAsyncError]].
|
||||
//
|
||||
// <Inline member functions for class [[GUSISMAsyncError]]>=
|
||||
inline int GUSISMAsyncError::SetAsyncPosixError(int error)
|
||||
{
|
||||
if (error) {
|
||||
fAsyncError = error;
|
||||
GUSI_MESSAGE(("GUSISMAsyncError::SetAsyncPosixError %d\n", fAsyncError));
|
||||
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
inline int GUSISMAsyncError::GetAsyncError()
|
||||
{
|
||||
int err = fAsyncError;
|
||||
fAsyncError = 0;
|
||||
return err;
|
||||
}
|
||||
// For some reason, the CW Pro 4 compilers generated bad code for this in some combination, so
|
||||
// we make it out of line.
|
||||
//
|
||||
// <Inline member functions for class [[GUSISMAsyncError]]>=
|
||||
inline int GUSISMAsyncError::SetAsyncMacError(OSErr error)
|
||||
{
|
||||
if (error) {
|
||||
fAsyncError = GUSIMapMacError(error);
|
||||
GUSI_MESSAGE(("GUSISMAsyncError::SetAsyncMacError %d -> %d\n", error, fAsyncError));
|
||||
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
// [[DoGetSockOpt]] only handles [[SO_ERROR]] (hi Philippe!).
|
||||
//
|
||||
// <Inline member functions for class [[GUSISMAsyncError]]>=
|
||||
inline bool GUSISMAsyncError::DoGetSockOpt(
|
||||
int * result, int level, int optname,
|
||||
void *optval, socklen_t * optlen)
|
||||
{
|
||||
if (level == SOL_SOCKET && optname == SO_ERROR) {
|
||||
*(int *)optval = GetAsyncError();
|
||||
*optlen = sizeof(int);
|
||||
|
||||
return (*result = 0), true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// <Inline member functions for class [[GUSISMProcess]]>=
|
||||
inline GUSISMProcess::GUSISMProcess()
|
||||
: fProcess(GUSIProcess::Instance())
|
||||
{
|
||||
}
|
||||
|
||||
inline GUSIProcess * GUSISMProcess::Process()
|
||||
{
|
||||
return fProcess;
|
||||
}
|
||||
|
||||
#endif /* GUSI_INTERNAL */
|
||||
|
||||
#endif /* _GUSISocketMixins_ */
|
|
@ -1,186 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSISpecific.nw - Thread specific variables
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:14 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.9 2000/10/16 04:11:21 neeri
|
||||
// % Plug memory leak
|
||||
// %
|
||||
// % Revision 1.8 2000/03/15 07:22:07 neeri
|
||||
// % Enforce alignment choices
|
||||
// %
|
||||
// % Revision 1.7 1999/08/26 05:45:10 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.6 1999/05/30 03:09:31 neeri
|
||||
// % Added support for MPW compilers
|
||||
// %
|
||||
// % Revision 1.5 1999/04/29 04:58:20 neeri
|
||||
// % Fix key destruction bug
|
||||
// %
|
||||
// % Revision 1.4 1999/03/17 09:05:13 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// % Revision 1.3 1998/10/11 16:45:25 neeri
|
||||
// % Ready to release 2.0a2
|
||||
// %
|
||||
// % Revision 1.2 1998/08/01 21:32:11 neeri
|
||||
// % About ready for 2.0a1
|
||||
// %
|
||||
// % Revision 1.1 1998/01/25 21:02:52 neeri
|
||||
// % Engine implemented, except for signals & scheduling
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{Thread Specific Variables}
|
||||
//
|
||||
// It is often useful to have variables which maintain a different value
|
||||
// for each process. The [[GUSISpecific]] class implements such a mechanism
|
||||
// in a way that is easily mappable to pthreads.
|
||||
//
|
||||
//
|
||||
// <GUSISpecific.h>=
|
||||
#ifndef _GUSISpecific_
|
||||
#define _GUSISpecific_
|
||||
|
||||
#ifndef GUSI_SOURCE
|
||||
|
||||
typedef struct GUSISpecific GUSISpecific;
|
||||
|
||||
#else
|
||||
|
||||
#include <Types.h>
|
||||
#include <ConditionalMacros.h>
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=native
|
||||
#endif
|
||||
|
||||
// \section{Definition of Thread Specific Variables}
|
||||
//
|
||||
// A [[GUSISpecific]] instance contains a variable ID and a per-process
|
||||
// destructor.
|
||||
//
|
||||
// <Definition of class [[GUSISpecific]]>=
|
||||
extern "C" {
|
||||
typedef void (*GUSISpecificDestructor)(void *);
|
||||
}
|
||||
|
||||
class GUSISpecific {
|
||||
friend class GUSISpecificTable;
|
||||
public:
|
||||
GUSISpecific(GUSISpecificDestructor destructor = nil);
|
||||
~GUSISpecific();
|
||||
|
||||
void Destruct(void * data);
|
||||
private:
|
||||
GUSISpecificDestructor fDestructor;
|
||||
unsigned fID;
|
||||
static unsigned sNextID;
|
||||
};
|
||||
// A [[GUSIContext]] contains a [[GUSISpecificTable]] storing the values of all
|
||||
// thread specific variables defined for this thread.
|
||||
//
|
||||
// <Definition of class [[GUSISpecificTable]]>=
|
||||
class GUSISpecificTable {
|
||||
friend class GUSISpecific;
|
||||
public:
|
||||
GUSISpecificTable();
|
||||
~GUSISpecificTable();
|
||||
void * GetSpecific(const GUSISpecific * key) const;
|
||||
void SetSpecific(const GUSISpecific * key, void * value);
|
||||
void DeleteSpecific(const GUSISpecific * key);
|
||||
private:
|
||||
static void Register(GUSISpecific * key);
|
||||
static void Destruct(GUSISpecific * key);
|
||||
|
||||
// We store a [[GUSISpecificTable]] as a contiguous range of IDs.
|
||||
//
|
||||
// <Privatissima of [[GUSISpecificTable]]>=
|
||||
void *** fValues;
|
||||
unsigned fAlloc;
|
||||
|
||||
bool Valid(const GUSISpecific * key) const;
|
||||
// All keys are registered in a global table.
|
||||
//
|
||||
// <Privatissima of [[GUSISpecificTable]]>=
|
||||
static GUSISpecific *** sKeys;
|
||||
static unsigned sKeyAlloc;
|
||||
};
|
||||
// To simplify having a particular variable assume a different instance in every
|
||||
// thread, we define the [[GUSISpecificData]] template.
|
||||
//
|
||||
// <Definition of template [[GUSISpecificData]]>=
|
||||
template <class T, GUSISpecificDestructor D>
|
||||
class GUSISpecificData {
|
||||
public:
|
||||
GUSISpecificData() : fKey(D) { }
|
||||
T & operator*() { return *get(); }
|
||||
T * operator->() { return get(); }
|
||||
|
||||
const GUSISpecific * Key() const { return &fKey; }
|
||||
T * get(GUSISpecificTable * table);
|
||||
T * get() { return get(GUSIContext::Current()); }
|
||||
protected:
|
||||
GUSISpecific fKey;
|
||||
};
|
||||
|
||||
template <class T, GUSISpecificDestructor D>
|
||||
T * GUSISpecificData<T,D>::get(GUSISpecificTable * table)
|
||||
{
|
||||
void * data = table->GetSpecific(&fKey);
|
||||
|
||||
if (!data)
|
||||
table->SetSpecific(&fKey, data = new T);
|
||||
|
||||
return static_cast<T *>(data);
|
||||
}
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=reset
|
||||
#endif
|
||||
|
||||
// <Inline member functions for class [[GUSISpecific]]>=
|
||||
inline GUSISpecific::GUSISpecific(GUSISpecificDestructor destructor)
|
||||
: fDestructor(destructor), fID(sNextID++)
|
||||
{
|
||||
GUSISpecificTable::Register(this);
|
||||
}
|
||||
|
||||
inline GUSISpecific::~GUSISpecific()
|
||||
{
|
||||
GUSISpecificTable::Destruct(this);
|
||||
}
|
||||
|
||||
inline void GUSISpecific::Destruct(void * data)
|
||||
{
|
||||
if (fDestructor)
|
||||
fDestructor(data);
|
||||
}
|
||||
// <Inline member functions for class [[GUSISpecificTable]]>=
|
||||
inline bool GUSISpecificTable::Valid(const GUSISpecific * key) const
|
||||
{
|
||||
return key && key->fID < fAlloc;
|
||||
}
|
||||
// <Inline member functions for class [[GUSISpecificTable]]>=
|
||||
inline GUSISpecificTable::GUSISpecificTable()
|
||||
: fValues(nil), fAlloc(0)
|
||||
{
|
||||
}
|
||||
// <Inline member functions for class [[GUSISpecificTable]]>=
|
||||
inline void * GUSISpecificTable::GetSpecific(const GUSISpecific * key) const
|
||||
{
|
||||
if (Valid(key))
|
||||
return fValues[0][key->fID];
|
||||
else
|
||||
return nil;
|
||||
}
|
||||
|
||||
#endif /* GUSI_SOURCE */
|
||||
|
||||
#endif /* _GUSISpecific_ */
|
|
@ -1,192 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSITimer.nw - Timing functions
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:16 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.12 2001/01/17 08:48:04 neeri
|
||||
// % Introduce Expired(), Reset()
|
||||
// %
|
||||
// % Revision 1.11 2000/10/29 18:36:32 neeri
|
||||
// % Fix time_t signedness issues
|
||||
// %
|
||||
// % Revision 1.10 2000/06/12 04:24:50 neeri
|
||||
// % Fix time, localtime, gmtime
|
||||
// %
|
||||
// % Revision 1.9 2000/05/23 07:24:58 neeri
|
||||
// % Improve formatting
|
||||
// %
|
||||
// % Revision 1.8 2000/03/15 07:22:07 neeri
|
||||
// % Enforce alignment choices
|
||||
// %
|
||||
// % Revision 1.7 1999/11/15 07:20:18 neeri
|
||||
// % Safe context setup
|
||||
// %
|
||||
// % Revision 1.6 1999/08/26 05:45:10 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.5 1999/08/02 07:02:46 neeri
|
||||
// % Support for asynchronous errors and other socket options
|
||||
// %
|
||||
// % Revision 1.4 1999/07/07 04:17:43 neeri
|
||||
// % Final tweaks for 2.0b3
|
||||
// %
|
||||
// % Revision 1.3 1999/06/28 06:08:46 neeri
|
||||
// % Support flexible timer classes
|
||||
// %
|
||||
// % Revision 1.2 1999/05/30 03:06:21 neeri
|
||||
// % Fixed various bugs in cleanup and wakeup
|
||||
// %
|
||||
// % Revision 1.1 1999/03/17 09:05:14 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{Timing functions}
|
||||
//
|
||||
// This section defines mechanisms to measure time. The basic mechanism is
|
||||
// [[GUSITimer]] which can wake up a [[GUSIContext]] at some later time.
|
||||
//
|
||||
// <GUSITimer.h>=
|
||||
#ifndef _GUSITimer_
|
||||
#define _GUSITimer_
|
||||
|
||||
#ifndef GUSI_SOURCE
|
||||
|
||||
typedef struct GUSITimer GUSITimer;
|
||||
|
||||
#else
|
||||
#include "GUSISpecific.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <MacTypes.h>
|
||||
#include <Timer.h>
|
||||
#include <Math64.h>
|
||||
|
||||
#include <ConditionalMacros.h>
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=native
|
||||
#endif
|
||||
|
||||
// \section{Definition of timing}
|
||||
//
|
||||
// [[GUSITime]] is an universal (if somewhat costly) format for
|
||||
// the large variety of timing formats used in MacOS and POSIX.
|
||||
//
|
||||
// <Definition of class [[GUSITime]]>=
|
||||
class GUSITime {
|
||||
public:
|
||||
enum Format {seconds, ticks, msecs, usecs, nsecs};
|
||||
|
||||
#if !TYPE_LONGLONG
|
||||
GUSITime(int32_t val, Format format);
|
||||
GUSITime(uint32_t val, Format format);
|
||||
#endif
|
||||
GUSITime(int64_t val, Format format=nsecs) { Construct(val, format); }
|
||||
GUSITime(const timeval & tv);
|
||||
GUSITime(const timespec & ts);
|
||||
GUSITime(const tm & t);
|
||||
GUSITime() {}
|
||||
|
||||
int32_t Get(Format format) { return S32Set(Get64(format)); }
|
||||
uint32_t UGet(Format format)
|
||||
{ return U32SetU(SInt64ToUInt64(Get64(format))); }
|
||||
int64_t Get64(Format format);
|
||||
|
||||
operator int64_t() { return fTime; }
|
||||
operator timeval();
|
||||
operator timespec();
|
||||
operator tm();
|
||||
|
||||
GUSITime GM2LocalTime();
|
||||
GUSITime Local2GMTime();
|
||||
|
||||
GUSITime & operator +=(const GUSITime & other)
|
||||
{ fTime = S64Add(fTime, other.fTime); return *this; }
|
||||
GUSITime & operator -=(const GUSITime & other)
|
||||
{ fTime = S64Subtract(fTime, other.fTime); return *this; }
|
||||
|
||||
|
||||
static GUSITime Now();
|
||||
static timezone & Zone();
|
||||
private:
|
||||
void Construct(int64_t val, Format format);
|
||||
time_t Deconstruct(int64_t & remainder);
|
||||
|
||||
int64_t fTime;
|
||||
|
||||
static int64_t sTimeOffset;
|
||||
static timezone sTimeZone;
|
||||
};
|
||||
|
||||
inline GUSITime operator+(const GUSITime & a, const GUSITime & b)
|
||||
{ GUSITime t(a); return t+=b; }
|
||||
inline GUSITime operator-(const GUSITime & a, const GUSITime & b)
|
||||
{ GUSITime t(a); return t-=b; }
|
||||
// A [[GUSITimer]] is a time manager task that wakes up a [[GUSIContext]].
|
||||
//
|
||||
// <Definition of class [[GUSITimer]]>=
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=mac68k
|
||||
#endif
|
||||
class GUSIContext;
|
||||
|
||||
extern "C" void GUSIKillTimers(void * timers);
|
||||
|
||||
class GUSITimer : public TMTask {
|
||||
public:
|
||||
GUSITimer(bool wakeup = true, GUSIContext * context = 0);
|
||||
virtual ~GUSITimer();
|
||||
|
||||
void Sleep(long ms, bool driftFree = false);
|
||||
void MicroSleep(long us, bool driftFree = false)
|
||||
{ Sleep(-us, driftFree); }
|
||||
GUSIContext * Context() { return fQueue->fContext; }
|
||||
GUSITimer * Next() { return fNext; }
|
||||
bool Primed() { return (qType&kTMTaskActive) != 0; }
|
||||
bool Expired() { return !(qType&kTMTaskActive); }
|
||||
virtual void Wakeup();
|
||||
void Kill();
|
||||
void Reset();
|
||||
|
||||
struct Queue {
|
||||
GUSITimer * fTimer;
|
||||
GUSIContext * fContext;
|
||||
|
||||
Queue() : fTimer(0) {}
|
||||
};
|
||||
|
||||
QElem * Elem() { return reinterpret_cast<QElem *>(&this->qLink); }
|
||||
protected:
|
||||
Queue * fQueue;
|
||||
GUSITimer * fNext;
|
||||
|
||||
class TimerQueue : public GUSISpecificData<Queue,GUSIKillTimers> {
|
||||
public:
|
||||
~TimerQueue();
|
||||
};
|
||||
|
||||
static TimerQueue sTimerQueue;
|
||||
static TimerUPP sTimerProc;
|
||||
};
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=reset
|
||||
#endif
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=reset
|
||||
#endif
|
||||
|
||||
#endif /* GUSI_SOURCE */
|
||||
|
||||
#endif /* _GUSITimer_ */
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* [¤3 Deleted as of 22Jul99, see
|
||||
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
|
||||
* for details]
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)inet.h 8.1 (Berkeley) 6/2/93
|
||||
*/
|
||||
|
||||
#ifndef _INET_H_
|
||||
#define _INET_H_
|
||||
|
||||
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
|
||||
|
||||
/* External definitions for functions in inet(3) */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
/* XNS mandates availability of xtonx() and uintx_t -- neeri */
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <machine/endian.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
in_addr_t inet_addr __P((const char *));
|
||||
int inet_aton __P((const char *, struct in_addr *));
|
||||
in_addr_t inet_lnaof __P((struct in_addr));
|
||||
struct in_addr inet_makeaddr __P((uint32_t , in_addr_t));
|
||||
in_addr_t inet_netof __P((struct in_addr));
|
||||
in_addr_t inet_network __P((const char *));
|
||||
char *inet_ntoa __P((struct in_addr));
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !_INET_H_ */
|
|
@ -1,66 +0,0 @@
|
|||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* [¤3 Deleted as of 22Jul99, see
|
||||
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
|
||||
* for details]
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)compat.h 8.1 (Berkeley) 6/2/93
|
||||
*/
|
||||
|
||||
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
|
||||
|
||||
#ifndef _COMPAT_H_
|
||||
#define _COMPAT_H_
|
||||
|
||||
/*
|
||||
* If your system doesn't specify a max size for a SIZE_T, check
|
||||
* to make sure this is the right one.
|
||||
*/
|
||||
#ifndef SIZE_T_MAX
|
||||
#define SIZE_T_MAX UINT_MAX
|
||||
#endif
|
||||
|
||||
#define index(a, b) strchr(a, b)
|
||||
#define rindex(a, b) strrchr(a, b)
|
||||
#define bzero(a, b) memset(a, 0, b)
|
||||
#define bcmp(a, b, n) memcmp(a, b, n)
|
||||
#define bcopy(a, b, n) memmove(b, a, n)
|
||||
|
||||
/* POSIX 1003.2 RE limit. */
|
||||
#ifndef _POSIX2_RE_DUP_MAX
|
||||
#define _POSIX2_RE_DUP_MAX 255
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(_a,_b) ((_a)<(_b)?(_b):(_a))
|
||||
#endif
|
||||
#ifndef MIN
|
||||
#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b))
|
||||
#endif
|
||||
|
||||
#endif /* !_COMPAT_H_ */
|
|
@ -1,56 +0,0 @@
|
|||
/*-
|
||||
* Copyright (c) 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* [¤3 Deleted as of 22Jul99, see
|
||||
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
|
||||
* for details]
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)dirent.h 8.1 (Berkeley) 6/8/93
|
||||
*/
|
||||
|
||||
#ifndef _DIRENT_H_
|
||||
#define _DIRENT_H_
|
||||
|
||||
struct dirent {
|
||||
ino_t d_ino; /* file number of entry */
|
||||
char d_name[255 + 1]; /* name must be no longer than this */
|
||||
};
|
||||
|
||||
typedef void * DIR;
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
DIR *opendir __P((const char *));
|
||||
struct dirent *readdir __P((DIR *));
|
||||
void rewinddir __P((DIR *));
|
||||
int closedir __P((DIR *));
|
||||
long telldir __P((DIR *));
|
||||
void seekdir __P((DIR *, long));
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !_DIRENT_H_ */
|
|
@ -1,51 +0,0 @@
|
|||
/* Metrowerks Standard Library Version 2.4 1998 March 10 */
|
||||
|
||||
/*
|
||||
* errno.h
|
||||
*/
|
||||
|
||||
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
|
||||
|
||||
#ifndef _ERRNO_H
|
||||
#define _ERRNO_H
|
||||
|
||||
#ifdef __MWERKS__
|
||||
#include <Types.h>
|
||||
#include <cerrno>
|
||||
/*
|
||||
* Undef error codes defined by MSL. We are overriding the MSL implementations, so
|
||||
* these versions of the codes should never be generated anyway.
|
||||
*/
|
||||
#undef EEXIST
|
||||
#undef ENOTEMPTY
|
||||
#undef EISDIR
|
||||
#undef EPERM
|
||||
#undef EACCES
|
||||
#undef EBADF
|
||||
#undef EDEADLOCK
|
||||
#undef EMFILE
|
||||
#undef ENOENT
|
||||
#undef ENFILE
|
||||
#undef ENOSPC
|
||||
#undef EINVAL
|
||||
#undef EIO
|
||||
#undef ENOMEM
|
||||
#undef ENOSYS
|
||||
#undef ENAMETOOLONG
|
||||
|
||||
#if UNIVERSAL_INTERFACES_VERSION >= 0x0340
|
||||
#undef EDEADLK
|
||||
#undef EAGAIN
|
||||
#endif
|
||||
|
||||
#else
|
||||
#include <mpw/errno.h>
|
||||
#endif
|
||||
|
||||
#include <sys/errno.h>
|
||||
|
||||
#if defined(__cplusplus) && defined(_MSL_USING_NAMESPACE) && (__MSL__ < 0x5000)
|
||||
using namespace std;
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,133 +0,0 @@
|
|||
/*-
|
||||
* Copyright (c) 1983, 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
* (c) UNIX System Laboratories, Inc.
|
||||
* All or some portions of this file are derived from material licensed
|
||||
* to the University of California by American Telephone and Telegraph
|
||||
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
|
||||
* the permission of UNIX System Laboratories, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* [¤3 Deleted as of 22Jul99, see
|
||||
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
|
||||
* for details]
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)fcntl.h 8.3 (Berkeley) 1/21/94
|
||||
*
|
||||
* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch>
|
||||
*/
|
||||
|
||||
#ifndef _FCNTL_H_
|
||||
#define _FCNTL_H_
|
||||
|
||||
/*
|
||||
* This file includes the definitions for open and fcntl
|
||||
* described by POSIX for <fcntl.h>; it also includes
|
||||
* related kernel definitions.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
/* open-only flags */
|
||||
#define O_RDONLY 0x0001 /* open for reading only */
|
||||
#define O_WRONLY 0x0002 /* open for writing only */
|
||||
#define O_RDWR 0x0000 /* open for reading and writing */
|
||||
#define O_ACCMODE 0x0003 /* mask for above modes */
|
||||
|
||||
#define O_NONBLOCK 0x0004 /* no delay */
|
||||
#define O_APPEND 0x0008 /* set append mode */
|
||||
#define O_CREAT 0x0200 /* create if nonexistant */
|
||||
#define O_TRUNC 0x0400 /* truncate to zero length */
|
||||
#define O_EXCL 0x0800 /* error if already exists */
|
||||
|
||||
#ifndef _POSIX_SOURCE
|
||||
/* Mac specific */
|
||||
#define O_ALIAS 0x2000 /* Open alias file (if the file is an alias) */
|
||||
#define O_RSRC 0x4000 /* Open the resource fork */
|
||||
#endif
|
||||
|
||||
/* defined by POSIX 1003.1; BSD default, so no bit required */
|
||||
#define O_NOCTTY 0 /* don't assign controlling terminal */
|
||||
|
||||
#ifndef _POSIX_SOURCE
|
||||
#define FNDELAY O_NONBLOCK /* compat */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Constants used for fcntl(2)
|
||||
*/
|
||||
|
||||
/* command values */
|
||||
#define F_DUPFD 0 /* duplicate file descriptor */
|
||||
#define F_GETFD 1 /* get file descriptor flags */
|
||||
#define F_SETFD 2 /* set file descriptor flags */
|
||||
#define F_GETFL 3 /* get file status flags */
|
||||
#define F_SETFL 4 /* set file status flags */
|
||||
#define F_GETOWN 5 /* get SIGIO/SIGURG proc/pgrp */
|
||||
#define F_SETOWN 6 /* set SIGIO/SIGURG proc/pgrp */
|
||||
#define F_GETLK 7 /* get record locking information */
|
||||
#define F_SETLK 8 /* set record locking information */
|
||||
#define F_SETLKW 9 /* F_SETLK; wait if blocked */
|
||||
|
||||
/* file descriptor flags (F_GETFD, F_SETFD) */
|
||||
#define FD_CLOEXEC 1 /* close-on-exec flag */
|
||||
|
||||
/* record locking flags (F_GETLK, F_SETLK, F_SETLKW) */
|
||||
#define F_RDLCK 1 /* shared or read lock */
|
||||
#define F_UNLCK 2 /* unlock */
|
||||
#define F_WRLCK 3 /* exclusive or write lock */
|
||||
|
||||
/*
|
||||
* Advisory file segment locking data type -
|
||||
* information passed to system by user
|
||||
*/
|
||||
struct flock {
|
||||
off_t l_start; /* starting offset */
|
||||
off_t l_len; /* len = 0 means until end of file */
|
||||
pid_t l_pid; /* lock owner */
|
||||
short l_type; /* lock type: read/write, etc. */
|
||||
short l_whence; /* type of l_start */
|
||||
};
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <stdio.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
int open __P((const char *, int, ...));
|
||||
int creat __P((const char *, ...));
|
||||
int fcntl __P((int, int, ...));
|
||||
|
||||
/* This properly belongs into stdio.h, but that header is outside of
|
||||
GUSI's control
|
||||
*/
|
||||
#if defined(__MWERKS__) && __MWERKS__ < 0x2401 && !defined(_SFSTDIO_H)
|
||||
FILE * fdopen(int fildes, char *type);
|
||||
#else
|
||||
FILE * fdopen(int fildes, const char *type);
|
||||
#endif
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !_FCNTL_H_ */
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
/* Written for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
|
||||
|
||||
#ifndef _INTTYPES_H_
|
||||
#define _INTTYPES_H_
|
||||
|
||||
/*
|
||||
* Regrettably, this is needed for *int64_t
|
||||
*/
|
||||
#include <MacTypes.h>
|
||||
#include <ansi_parms.h>
|
||||
|
||||
#if __MSL__ < 0x7001
|
||||
#if __MSL__ < 0x6000
|
||||
typedef char int8_t;
|
||||
#else
|
||||
typedef signed char int8_t;
|
||||
#endif
|
||||
typedef short int16_t;
|
||||
typedef long int32_t;
|
||||
typedef SInt64 int64_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned long uint32_t;
|
||||
typedef UInt64 uint64_t;
|
||||
typedef long intptr_t;
|
||||
typedef unsigned long uintptr_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#endif /* _INTTYPES_H_ */
|
|
@ -1,73 +0,0 @@
|
|||
/*-
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* [¤3 Deleted as of 22Jul99, see
|
||||
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
|
||||
* for details]
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ansi.h 8.2 (Berkeley) 1/4/94
|
||||
*/
|
||||
|
||||
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
|
||||
|
||||
#ifndef _ANSI_H_
|
||||
#define _ANSI_H_
|
||||
|
||||
/*
|
||||
* Types which are fundamental to the implementation and may appear in
|
||||
* more than one standard header are defined here. Standard headers
|
||||
* then use:
|
||||
* #ifdef _BSD_SIZE_T_
|
||||
* typedef _BSD_SIZE_T_ size_t;
|
||||
* #undef _BSD_SIZE_T_
|
||||
* #endif
|
||||
*/
|
||||
#define _BSD_CLOCK_T_ unsigned long /* clock() */
|
||||
#define _BSD_PTRDIFF_T_ int /* ptr1 - ptr2 */
|
||||
#define _BSD_SIZE_T_ unsigned long /* sizeof() */
|
||||
#define _BSD_SSIZE_T_ long /* byte count or error */
|
||||
#define _BSD_TIME_T_ unsigned long /* time() */
|
||||
#define _BSD_VA_LIST_ char * /* va_list */
|
||||
|
||||
/*
|
||||
* Runes (wchar_t) is declared to be an ``int'' instead of the more natural
|
||||
* ``unsigned long'' or ``long''. Two things are happening here. It is not
|
||||
* unsigned so that EOF (-1) can be naturally assigned to it and used. Also,
|
||||
* it looks like 10646 will be a 31 bit standard. This means that if your
|
||||
* ints cannot hold 32 bits, you will be in trouble. The reason an int was
|
||||
* chosen over a long is that the is*() and to*() routines take ints (says
|
||||
* ANSI C), but they use _RUNE_T_ instead of int. By changing it here, you
|
||||
* lose a bit of ANSI conformance, but your programs will still work.
|
||||
*
|
||||
* Note that _WCHAR_T_ and _RUNE_T_ must be of the same type. When wchar_t
|
||||
* and rune_t are typedef'd, _WCHAR_T_ will be undef'd, but _RUNE_T remains
|
||||
* defined for ctype.h.
|
||||
*/
|
||||
#define _BSD_WCHAR_T_ int /* wchar_t */
|
||||
#define _BSD_RUNE_T_ int /* rune_t */
|
||||
|
||||
#endif /* _ANSI_H_ */
|
|
@ -1,84 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1987, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* [¤3 Deleted as of 22Jul99, see
|
||||
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
|
||||
* for details]
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)endian.h 8.1 (Berkeley) 6/10/93
|
||||
*/
|
||||
|
||||
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
|
||||
|
||||
#ifndef _ENDIAN_H_
|
||||
#define _ENDIAN_H_
|
||||
|
||||
/* xtonx() now defined in terms of inttypes -- neeri */
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
/*
|
||||
* Define the order of 32-bit words in 64-bit words.
|
||||
*/
|
||||
#define _QUAD_HIGHWORD 0
|
||||
#define _QUAD_LOWWORD 1
|
||||
|
||||
#ifndef _POSIX_SOURCE
|
||||
/*
|
||||
* Definitions for byte order, according to byte significance from low
|
||||
* address to high.
|
||||
*/
|
||||
#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax */
|
||||
#define BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */
|
||||
#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long */
|
||||
|
||||
#define BYTE_ORDER BIG_ENDIAN
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
uint32_t htonl __P((uint32_t));
|
||||
uint16_t htons __P((uint16_t));
|
||||
uint32_t ntohl __P((uint32_t));
|
||||
uint16_t ntohs __P((uint16_t));
|
||||
__END_DECLS
|
||||
|
||||
/*
|
||||
* Macros for network/external number representation conversion.
|
||||
*/
|
||||
#define ntohl(x) (x)
|
||||
#define ntohs(x) (x)
|
||||
#define htonl(x) (x)
|
||||
#define htons(x) (x)
|
||||
|
||||
#define NTOHL(x) (x)
|
||||
#define NTOHS(x) (x)
|
||||
#define HTONL(x) (x)
|
||||
#define HTONS(x) (x)
|
||||
|
||||
#endif /* !_POSIX_SOURCE */
|
||||
#endif /* !_ENDIAN_H_ */
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1986, 1989, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* [¤3 Deleted as of 22Jul99, see
|
||||
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
|
||||
* for details]
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)signal.h 8.1 (Berkeley) 6/10/93
|
||||
*/
|
||||
|
||||
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
|
||||
|
||||
/*
|
||||
* Machine-dependent signal definitions
|
||||
*/
|
||||
|
||||
typedef int sig_atomic_t;
|
|
@ -1,131 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1982, 1986, 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* [¤3 Deleted as of 22Jul99, see
|
||||
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
|
||||
* for details]
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)if.h 8.1 (Berkeley) 6/10/93
|
||||
*/
|
||||
|
||||
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
|
||||
|
||||
/*
|
||||
* Structures defining a network interface, providing a packet
|
||||
* transport mechanism (ala level 0 of the PUP protocols).
|
||||
*
|
||||
* Each interface accepts output datagrams of a specified maximum
|
||||
* length, and provides higher level routines with input datagrams
|
||||
* received from its medium.
|
||||
*
|
||||
* Output occurs when the routine if_output is called, with three parameters:
|
||||
* (*ifp->if_output)(ifp, m, dst, rt)
|
||||
* Here m is the mbuf chain to be sent and dst is the destination address.
|
||||
* The output routine encapsulates the supplied datagram if necessary,
|
||||
* and then transmits it on its medium.
|
||||
*
|
||||
* On input, each interface unwraps the data received by it, and either
|
||||
* places it on the input queue of a internetwork datagram routine
|
||||
* and posts the associated software interrupt, or passes the datagram to a raw
|
||||
* packet input routine.
|
||||
*
|
||||
* Routines exist for locating interfaces by their addresses
|
||||
* or for locating a interface on a certain network, as well as more general
|
||||
* routing and gateway routines maintaining information used to locate
|
||||
* interfaces. These routines live in the files if.c and route.c
|
||||
*/
|
||||
|
||||
#define IFF_UP 0x1 /* interface is up */
|
||||
#define IFF_BROADCAST 0x2 /* broadcast address valid */
|
||||
#define IFF_DEBUG 0x4 /* turn on debugging */
|
||||
#define IFF_LOOPBACK 0x8 /* is a loopback net */
|
||||
#define IFF_POINTOPOINT 0x10 /* interface is point-to-point link */
|
||||
#define IFF_NOTRAILERS 0x20 /* avoid use of trailers */
|
||||
#define IFF_RUNNING 0x40 /* resources allocated */
|
||||
#define IFF_NOARP 0x80 /* no address resolution protocol */
|
||||
#define IFF_PROMISC 0x100 /* receive all packets */
|
||||
#define IFF_ALLMULTI 0x200 /* receive all multicast packets */
|
||||
#define IFF_OACTIVE 0x400 /* transmission in progress */
|
||||
#define IFF_SIMPLEX 0x800 /* can't hear own transmissions */
|
||||
#define IFF_LINK0 0x1000 /* per link layer defined bit */
|
||||
#define IFF_LINK1 0x2000 /* per link layer defined bit */
|
||||
#define IFF_LINK2 0x4000 /* per link layer defined bit */
|
||||
#define IFF_MULTICAST 0x8000 /* supports multicast */
|
||||
|
||||
/* flags set internally only: */
|
||||
#define IFF_CANTCHANGE \
|
||||
(IFF_BROADCAST|IFF_POINTOPOINT|IFF_RUNNING|IFF_OACTIVE|\
|
||||
IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI)
|
||||
|
||||
/*
|
||||
* Interface request structure used for socket
|
||||
* ioctl's. All interface ioctl's must have parameter
|
||||
* definitions which begin with ifr_name. The
|
||||
* remainder may be interface specific.
|
||||
*/
|
||||
struct ifreq {
|
||||
#define IFNAMSIZ 16
|
||||
char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */
|
||||
union {
|
||||
struct sockaddr ifru_addr;
|
||||
struct sockaddr ifru_dstaddr;
|
||||
struct sockaddr ifru_broadaddr;
|
||||
short ifru_flags;
|
||||
int ifru_metric;
|
||||
caddr_t ifru_data;
|
||||
} ifr_ifru;
|
||||
#define ifr_addr ifr_ifru.ifru_addr /* address */
|
||||
#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */
|
||||
#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
|
||||
#define ifr_flags ifr_ifru.ifru_flags /* flags */
|
||||
#define ifr_metric ifr_ifru.ifru_metric /* metric */
|
||||
#define ifr_data ifr_ifru.ifru_data /* for use by interface */
|
||||
};
|
||||
|
||||
struct ifaliasreq {
|
||||
char ifra_name[IFNAMSIZ]; /* if name, e.g. "en0" */
|
||||
struct sockaddr ifra_addr;
|
||||
struct sockaddr ifra_broadaddr;
|
||||
struct sockaddr ifra_mask;
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure used in SIOCGIFCONF request.
|
||||
* Used to retrieve interface configuration
|
||||
* for machine (useful for programs which
|
||||
* must know all networks accessible).
|
||||
*/
|
||||
struct ifconf {
|
||||
int ifc_len; /* size of associated buffer */
|
||||
union {
|
||||
caddr_t ifcu_buf;
|
||||
struct ifreq *ifcu_req;
|
||||
} ifc_ifcu;
|
||||
#define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */
|
||||
#define ifc_req ifc_ifcu.ifcu_req /* array of structures returned */
|
||||
};
|
||||
|
|
@ -1,128 +0,0 @@
|
|||
/*-
|
||||
* Copyright (c) 1980, 1983, 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* [¤3 Deleted as of 22Jul99, see
|
||||
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
|
||||
* for details]
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)netdb.h 8.1 (Berkeley) 6/2/93
|
||||
* $Id$
|
||||
* -
|
||||
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies, and that
|
||||
* the name of Digital Equipment Corporation not be used in advertising or
|
||||
* publicity pertaining to distribution of the document or software without
|
||||
* specific, written prior permission.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
|
||||
* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
* -
|
||||
* --Copyright--
|
||||
*/
|
||||
|
||||
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
|
||||
|
||||
#ifndef _NETDB_H_
|
||||
#define _NETDB_H_
|
||||
|
||||
#define _PATH_HEQUIV "/etc/hosts.equiv"
|
||||
#define _PATH_HOSTS "/etc/hosts"
|
||||
#define _PATH_NETWORKS "/etc/networks"
|
||||
#define _PATH_PROTOCOLS "/etc/protocols"
|
||||
#define _PATH_SERVICES "/etc/services"
|
||||
|
||||
/*
|
||||
* Structures returned by network data base library. All addresses are
|
||||
* supplied in host order, and returned in network order (suitable for
|
||||
* use in system calls).
|
||||
*/
|
||||
struct hostent {
|
||||
char *h_name; /* official name of host */
|
||||
char **h_aliases; /* alias list */
|
||||
int h_addrtype; /* host address type */
|
||||
int h_length; /* length of address */
|
||||
char **h_addr_list; /* list of addresses from name server */
|
||||
#define h_addr h_addr_list[0] /* address, for backward compatiblity */
|
||||
};
|
||||
|
||||
struct servent {
|
||||
char *s_name; /* official service name */
|
||||
char **s_aliases; /* alias list */
|
||||
int s_port; /* port # */
|
||||
char *s_proto; /* protocol to use */
|
||||
};
|
||||
|
||||
struct protoent {
|
||||
char *p_name; /* official protocol name */
|
||||
char **p_aliases; /* alias list */
|
||||
int p_proto; /* protocol # */
|
||||
};
|
||||
|
||||
/*
|
||||
* Error return codes from gethostbyname() and gethostbyaddr()
|
||||
* (left in h_errno).
|
||||
*/
|
||||
|
||||
extern int h_errno;
|
||||
|
||||
#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */
|
||||
#define TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */
|
||||
#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
|
||||
#define NO_DATA 4 /* Valid name, no data record of requested type */
|
||||
#define NO_ADDRESS NO_DATA /* no address, look for MX record */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
void endhostent __P((void));
|
||||
void endprotoent __P((void));
|
||||
void endservent __P((void));
|
||||
struct hostent *gethostbyaddr __P((const void *, size_t, int));
|
||||
struct hostent *gethostbyname __P((const char *));
|
||||
struct hostent *gethostent __P((void));
|
||||
struct protoent *getprotobyname __P((const char *));
|
||||
struct protoent *getprotobynumber __P((int));
|
||||
struct protoent *getprotoent __P((void));
|
||||
struct servent *getservbyname __P((const char *, const char *));
|
||||
struct servent *getservbyport __P((int, const char *));
|
||||
struct servent *getservent __P((void));
|
||||
void herror __P((const char *));
|
||||
char *hstrerror __P((int));
|
||||
void setprotoent __P((int));
|
||||
void setservent __P((int));
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !_NETDB_H_ */
|
|
@ -1,249 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1982, 1986, 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* [¤3 Deleted as of 22Jul99, see
|
||||
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
|
||||
* for details]
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)in.h 8.3 (Berkeley) 1/3/94
|
||||
*/
|
||||
|
||||
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
|
||||
|
||||
#ifndef _NETINET_IN_H_
|
||||
#define _NETINET_IN_H_
|
||||
|
||||
/* xtonx() mandated available by XNS -- neeri */
|
||||
#include <machine/endian.h>
|
||||
|
||||
/*
|
||||
* Constants and structures defined by the internet system,
|
||||
* Per RFC 790, September 1981, and numerous additions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Protocols
|
||||
*/
|
||||
#define IPPROTO_IP 0 /* dummy for IP */
|
||||
#define IPPROTO_ICMP 1 /* control message protocol */
|
||||
#define IPPROTO_IGMP 2 /* group mgmt protocol */
|
||||
#define IPPROTO_GGP 3 /* gateway^2 (deprecated) */
|
||||
#define IPPROTO_TCP 6 /* tcp */
|
||||
#define IPPROTO_EGP 8 /* exterior gateway protocol */
|
||||
#define IPPROTO_PUP 12 /* pup */
|
||||
#define IPPROTO_UDP 17 /* user datagram protocol */
|
||||
#define IPPROTO_IDP 22 /* xns idp */
|
||||
#define IPPROTO_TP 29 /* tp-4 w/ class negotiation */
|
||||
#define IPPROTO_EON 80 /* ISO cnlp */
|
||||
#define IPPROTO_ENCAP 98 /* encapsulation header */
|
||||
|
||||
#define IPPROTO_RAW 255 /* raw IP packet */
|
||||
#define IPPROTO_MAX 256
|
||||
|
||||
|
||||
/*
|
||||
* Local port number conventions:
|
||||
* Ports < IPPORT_RESERVED are reserved for
|
||||
* privileged processes (e.g. root).
|
||||
* Ports > IPPORT_USERRESERVED are reserved
|
||||
* for servers, not necessarily privileged.
|
||||
*/
|
||||
#define IPPORT_RESERVED 1024
|
||||
#define IPPORT_USERRESERVED 5000
|
||||
|
||||
/* Types mandated by XNS -- neeri */
|
||||
typedef uint16_t in_port_t;
|
||||
typedef uint32_t in_addr_t;
|
||||
|
||||
/*
|
||||
* Internet address (a structure for historical reasons)
|
||||
*/
|
||||
struct in_addr {
|
||||
in_addr_t s_addr;
|
||||
};
|
||||
|
||||
/*
|
||||
* Definitions of bits in internet address integers.
|
||||
* On subnets, the decomposition of addresses to host and net parts
|
||||
* is done according to subnet mask, not the masks here.
|
||||
*/
|
||||
#define IN_CLASSA(i) (((long)(i) & 0x80000000) == 0)
|
||||
#define IN_CLASSA_NET 0xff000000
|
||||
#define IN_CLASSA_NSHIFT 24
|
||||
#define IN_CLASSA_HOST 0x00ffffff
|
||||
#define IN_CLASSA_MAX 128
|
||||
|
||||
#define IN_CLASSB(i) (((long)(i) & 0xc0000000) == 0x80000000)
|
||||
#define IN_CLASSB_NET 0xffff0000
|
||||
#define IN_CLASSB_NSHIFT 16
|
||||
#define IN_CLASSB_HOST 0x0000ffff
|
||||
#define IN_CLASSB_MAX 65536
|
||||
|
||||
#define IN_CLASSC(i) (((long)(i) & 0xe0000000) == 0xc0000000)
|
||||
#define IN_CLASSC_NET 0xffffff00
|
||||
#define IN_CLASSC_NSHIFT 8
|
||||
#define IN_CLASSC_HOST 0x000000ff
|
||||
|
||||
#define IN_CLASSD(i) (((long)(i) & 0xf0000000) == 0xe0000000)
|
||||
#define IN_CLASSD_NET 0xf0000000 /* These ones aren't really */
|
||||
#define IN_CLASSD_NSHIFT 28 /* net and host fields, but */
|
||||
#define IN_CLASSD_HOST 0x0fffffff /* routing needn't know. */
|
||||
#define IN_MULTICAST(i) IN_CLASSD(i)
|
||||
|
||||
#define IN_EXPERIMENTAL(i) (((long)(i) & 0xf0000000) == 0xf0000000)
|
||||
#define IN_BADCLASS(i) (((long)(i) & 0xf0000000) == 0xf0000000)
|
||||
|
||||
#define INADDR_ANY (u_long)0x00000000
|
||||
#define INADDR_BROADCAST (u_long)0xffffffff /* must be masked */
|
||||
#define INADDR_NONE 0xffffffff /* -1 return */
|
||||
|
||||
#define INADDR_UNSPEC_GROUP (u_long)0xe0000000 /* 224.0.0.0 */
|
||||
#define INADDR_ALLHOSTS_GROUP (u_long)0xe0000001 /* 224.0.0.1 */
|
||||
#define INADDR_MAX_LOCAL_GROUP (u_long)0xe00000ff /* 224.0.0.255 */
|
||||
|
||||
#define IN_LOOPBACKNET 127 /* official! */
|
||||
|
||||
/* Mandated by XNS -- neeri */
|
||||
#ifndef _SA_FAMILY_T_DEFINED
|
||||
#define _SA_FAMILY_T_DEFINED
|
||||
typedef uint16_t sa_family_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Socket address, internet style.
|
||||
*/
|
||||
struct sockaddr_in {
|
||||
sa_family_t sin_family;
|
||||
in_port_t sin_port;
|
||||
struct in_addr sin_addr;
|
||||
unsigned char sin_zero[8];
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure used to describe IP options.
|
||||
* Used to store options internally, to pass them to a process,
|
||||
* or to restore options retrieved earlier.
|
||||
* The ip_dst is used for the first-hop gateway when using a source route
|
||||
* (this gets put into the header proper).
|
||||
*/
|
||||
typedef struct {
|
||||
struct in_addr ip_dst; /* first hop, 0 w/o src rt */
|
||||
char ip_opts[40]; /* actually variable in size */
|
||||
} ip_opts;
|
||||
|
||||
/*
|
||||
* Options for use with [gs]etsockopt at the IP level.
|
||||
* First word of comment is data type; bool is stored in int.
|
||||
*/
|
||||
#define IP_OPTIONS 0x01
|
||||
#define IP_TOS 0x02
|
||||
#define IP_TTL 0x03
|
||||
#define IP_REUSEADDR 0x04
|
||||
#define IP_DONTROUTE 0x10
|
||||
#define IP_BROADCAST 0x20
|
||||
#define IP_HDRINCL 0x1002
|
||||
#define IP_RCVOPTS 0x1005
|
||||
#define IP_RCVDSTADDR 0x1007
|
||||
#define IP_MULTICAST_IF 0x1010 /* set/get IP multicast interface */
|
||||
#define IP_MULTICAST_TTL 0x1011 /* set/get IP multicast timetolive */
|
||||
#define IP_MULTICAST_LOOP 0x1012 /* set/get IP multicast loopback */
|
||||
#define IP_ADD_MEMBERSHIP 0x1013 /* add an IP group membership */
|
||||
#define IP_DROP_MEMBERSHIP 0x1014 /* drop an IP group membership */
|
||||
#define IP_BROADCAST_IF 0x1015 /* Set interface for broadcasts */
|
||||
#define IP_RCVIFADDR 0x1016 /* Set interface for broadcasts */
|
||||
|
||||
|
||||
/*
|
||||
* Defaults and limits for options
|
||||
*/
|
||||
#define IP_DEFAULT_MULTICAST_TTL 1 /* normally limit m'casts to 1 hop */
|
||||
#define IP_DEFAULT_MULTICAST_LOOP 1 /* normally hear sends if a member */
|
||||
#define IP_MAX_MEMBERSHIPS 20 /* per socket; must fit in one mbuf */
|
||||
|
||||
/*
|
||||
* Argument structure for IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP.
|
||||
*/
|
||||
struct ip_mreq {
|
||||
struct in_addr imr_multiaddr; /* IP multicast address of group */
|
||||
struct in_addr imr_interface; /* local IP address of interface */
|
||||
};
|
||||
|
||||
/*
|
||||
* Definitions for inet sysctl operations.
|
||||
*
|
||||
* Third level is protocol number.
|
||||
* Fourth level is desired variable within that protocol.
|
||||
*/
|
||||
#define IPPROTO_MAXID (IPPROTO_IDP + 1) /* don't list to IPPROTO_MAX */
|
||||
|
||||
#define CTL_IPPROTO_NAMES { \
|
||||
{ "ip", CTLTYPE_NODE }, \
|
||||
{ "icmp", CTLTYPE_NODE }, \
|
||||
{ "igmp", CTLTYPE_NODE }, \
|
||||
{ "ggp", CTLTYPE_NODE }, \
|
||||
{ 0, 0 }, \
|
||||
{ 0, 0 }, \
|
||||
{ "tcp", CTLTYPE_NODE }, \
|
||||
{ 0, 0 }, \
|
||||
{ "egp", CTLTYPE_NODE }, \
|
||||
{ 0, 0 }, \
|
||||
{ 0, 0 }, \
|
||||
{ 0, 0 }, \
|
||||
{ "pup", CTLTYPE_NODE }, \
|
||||
{ 0, 0 }, \
|
||||
{ 0, 0 }, \
|
||||
{ 0, 0 }, \
|
||||
{ 0, 0 }, \
|
||||
{ "udp", CTLTYPE_NODE }, \
|
||||
{ 0, 0 }, \
|
||||
{ 0, 0 }, \
|
||||
{ 0, 0 }, \
|
||||
{ 0, 0 }, \
|
||||
{ "idp", CTLTYPE_NODE }, \
|
||||
}
|
||||
|
||||
/*
|
||||
* Names for IP sysctl objects
|
||||
*/
|
||||
#define IPCTL_FORWARDING 1 /* act as router */
|
||||
#define IPCTL_SENDREDIRECTS 2 /* may send redirects when forwarding */
|
||||
#define IPCTL_DEFTTL 3 /* default TTL */
|
||||
#ifdef notyet
|
||||
#define IPCTL_DEFMTU 4 /* default MTU */
|
||||
#endif
|
||||
#define IPCTL_MAXID 5
|
||||
|
||||
#define IPCTL_NAMES { \
|
||||
{ 0, 0 }, \
|
||||
{ "forwarding", CTLTYPE_INT }, \
|
||||
{ "redirect", CTLTYPE_INT }, \
|
||||
{ "ttl", CTLTYPE_INT }, \
|
||||
{ "mtu", CTLTYPE_INT }, \
|
||||
}
|
||||
|
||||
#endif /* _NETINET_IN_H_ */
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1982, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* [¤3 Deleted as of 22Jul99, see
|
||||
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
|
||||
* for details]
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)tcp.h 8.1 (Berkeley) 6/10/93
|
||||
*/
|
||||
|
||||
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
|
||||
|
||||
typedef u_long tcp_seq;
|
||||
/*
|
||||
* TCP header.
|
||||
* Per RFC 793, September, 1981.
|
||||
*/
|
||||
struct tcphdr {
|
||||
u_short th_sport; /* source port */
|
||||
u_short th_dport; /* destination port */
|
||||
tcp_seq th_seq; /* sequence number */
|
||||
tcp_seq th_ack; /* acknowledgement number */
|
||||
u_char th_off:4, /* data offset */
|
||||
th_x2:4; /* (unused) */
|
||||
u_char th_flags;
|
||||
#define TH_FIN 0x01
|
||||
#define TH_SYN 0x02
|
||||
#define TH_RST 0x04
|
||||
#define TH_PUSH 0x08
|
||||
#define TH_ACK 0x10
|
||||
#define TH_URG 0x20
|
||||
u_short th_win; /* window */
|
||||
u_short th_sum; /* checksum */
|
||||
u_short th_urp; /* urgent pointer */
|
||||
};
|
||||
|
||||
#define TCPOPT_EOL 0
|
||||
#define TCPOPT_NOP 1
|
||||
#define TCPOPT_MAXSEG 2
|
||||
#define TCPOLEN_MAXSEG 4
|
||||
#define TCPOPT_WINDOW 3
|
||||
#define TCPOLEN_WINDOW 3
|
||||
#define TCPOPT_SACK_PERMITTED 4 /* Experimental */
|
||||
#define TCPOLEN_SACK_PERMITTED 2
|
||||
#define TCPOPT_SACK 5 /* Experimental */
|
||||
#define TCPOPT_TIMESTAMP 8
|
||||
#define TCPOLEN_TIMESTAMP 10
|
||||
#define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */
|
||||
|
||||
#define TCPOPT_TSTAMP_HDR \
|
||||
(TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP)
|
||||
|
||||
/*
|
||||
* Default maximum segment size for TCP.
|
||||
* With an IP MSS of 576, this is 536,
|
||||
* but 512 is probably more convenient.
|
||||
* This should be defined as MIN(512, IP_MSS - sizeof (struct tcpiphdr)).
|
||||
*/
|
||||
#define TCP_MSS 512
|
||||
|
||||
#define TCP_MAXWIN 65535 /* largest value for (unscaled) window */
|
||||
|
||||
#define TCP_MAX_WINSHIFT 14 /* maximum window shift */
|
||||
|
||||
/*
|
||||
* User-settable options (used with setsockopt).
|
||||
*/
|
||||
#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */
|
||||
#define TCP_MAXSEG 0x02 /* set maximum segment size */
|
||||
#define TCP_KEEPALIVE 0x08 /* seconds between keepalive packets */
|
|
@ -1,299 +0,0 @@
|
|||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// % Project : GUSI - Grand Unified Socket Interface
|
||||
// % File : GUSIPThread.nw - Pthreads wrappers
|
||||
// % Author : Matthias Neeracher
|
||||
// % Language : C++
|
||||
// %
|
||||
// % $Log$
|
||||
// % Revision 1.1.1.1 2001/03/03 21:50:16 chombier
|
||||
// % Initial import
|
||||
// %
|
||||
// % Revision 1.14 2001/01/17 08:55:16 neeri
|
||||
// % Detect and return ETIMEDOUT condition
|
||||
// %
|
||||
// % Revision 1.13 2000/10/29 20:31:53 neeri
|
||||
// % Releasing 2.1.3
|
||||
// %
|
||||
// % Revision 1.12 2000/05/23 07:16:35 neeri
|
||||
// % Improve formatting, make data types opaque, tune mutexes
|
||||
// %
|
||||
// % Revision 1.11 2000/03/06 06:10:00 neeri
|
||||
// % Reorganize Yield()
|
||||
// %
|
||||
// % Revision 1.10 2000/01/17 01:40:31 neeri
|
||||
// % Correct macro spelling, update references
|
||||
// %
|
||||
// % Revision 1.9 1999/11/15 07:20:19 neeri
|
||||
// % Safe context setup
|
||||
// %
|
||||
// % Revision 1.8 1999/09/09 07:22:15 neeri
|
||||
// % Add support for mutex and cond attribute creation/destruction
|
||||
// %
|
||||
// % Revision 1.7 1999/08/26 05:45:07 neeri
|
||||
// % Fixes for literate edition of source code
|
||||
// %
|
||||
// % Revision 1.6 1999/07/07 04:17:42 neeri
|
||||
// % Final tweaks for 2.0b3
|
||||
// %
|
||||
// % Revision 1.5 1999/06/30 07:42:07 neeri
|
||||
// % Getting ready to release 2.0b3
|
||||
// %
|
||||
// % Revision 1.4 1999/05/30 03:06:55 neeri
|
||||
// % MPW compiler compatibility, recursive mutex locks
|
||||
// %
|
||||
// % Revision 1.3 1999/03/17 09:05:12 neeri
|
||||
// % Added GUSITimer, expanded docs
|
||||
// %
|
||||
// % Revision 1.2 1998/08/01 21:32:10 neeri
|
||||
// % About ready for 2.0a1
|
||||
// %
|
||||
// % Revision 1.1 1998/01/25 21:02:51 neeri
|
||||
// % Engine implemented, except for signals & scheduling
|
||||
// %
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// \chapter{Pthreads Wrappers}
|
||||
//
|
||||
// As opposed to POSIX.1, with which I think I'm reasonable competent by now,
|
||||
// I have little practical experience, let alone in-depth familiarity with
|
||||
// Pthreads, so I'm going by what I learned from
|
||||
//
|
||||
// \begin{itemize}
|
||||
// \item Reading \emph{B.~Nicols, D.~Buttlar, and J.~Proulx Farrell,
|
||||
// ``Pthreads Programming'', O'Reilly \& Associates} and
|
||||
// \emph{D.~Butenhof, ``Programming with POSIX Threads'', Addison Wesley}.
|
||||
//
|
||||
// \item Taking a few glimpses at Chris Provenzano's pthreads implementation.
|
||||
// \item Reading the news:comp.programming.threads newsgroup.
|
||||
// \end{itemize}
|
||||
//
|
||||
// If you believe that I've misunderstood Pthreads in my implementation, feel free
|
||||
// to contact me.
|
||||
//
|
||||
// As opposed to most other modules, the header files we're generating here don't
|
||||
// have GUSI in its name.
|
||||
//
|
||||
// <pthread.h>=
|
||||
#ifndef _PTHREAD_H_
|
||||
#define _PTHREAD_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
// \section{Definition of Pthread data types}
|
||||
//
|
||||
// I used to be fairly cavalier about exposing internal GUSI data structures,
|
||||
// on second thought this was not a good idea. To keep C happy, we define
|
||||
// [[struct]] wrappers for what ultimately will mostly be classes.
|
||||
//
|
||||
// <Pthread data types>=
|
||||
typedef struct GUSIPThread * pthread_t;
|
||||
// A [[pthread_attr_t]] collects thread creation attributes. This is implemented
|
||||
// as a pointer so it's easier to change the size of the underlying data structure.
|
||||
//
|
||||
// <Pthread data types>=
|
||||
typedef struct GUSIPThreadAttr * pthread_attr_t;
|
||||
// A [[pthread_key_t]] is a key to look up thread specific data.
|
||||
//
|
||||
// <Pthread data types>=
|
||||
typedef struct GUSIPThreadKey * pthread_key_t;
|
||||
// A [[pthread_once_t]] registers whether some routine has run once. It must always
|
||||
// be statically initialized to [[PTHREAD_ONCE_INIT]] (Although in our implementation,
|
||||
// it doesn't matter).
|
||||
//
|
||||
// <Pthread data types>=
|
||||
typedef char pthread_once_t;
|
||||
|
||||
enum {
|
||||
PTHREAD_ONCE_INIT = 0
|
||||
};
|
||||
// A [[pthread_mutex_t]] is a mutual exclusion variable, implemented as a pointer
|
||||
// to a [[GUSIContextQueue]]. For initialization convenience, a 0 value means
|
||||
// an unlocked mutex. No attributes are supported so far.
|
||||
//
|
||||
// <Pthread data types>=
|
||||
typedef struct GUSIPThreadMutex * pthread_mutex_t;
|
||||
typedef void * pthread_mutexattr_t;
|
||||
|
||||
#define PTHREAD_MUTEX_INITIALIZER 0
|
||||
// A [[pthread_cond_t]] is a condition variable, which looks rather similar
|
||||
// to a mutex, but has different semantics. No attributes are supported so far.
|
||||
//
|
||||
// <Pthread data types>=
|
||||
typedef struct GUSIPThreadCond * pthread_cond_t;
|
||||
typedef void * pthread_condattr_t;
|
||||
|
||||
#define PTHREAD_COND_INITIALIZER 0
|
||||
// [[pthread_attr_init]] initializes an attribute object with the
|
||||
// default values.
|
||||
//
|
||||
// <Pthread function declarations>=
|
||||
int pthread_attr_init(pthread_attr_t * attr);
|
||||
// [[pthread_attr_destroy]] destroys an attribute object.
|
||||
//
|
||||
// <Pthread function declarations>=
|
||||
int pthread_attr_destroy(pthread_attr_t * attr);
|
||||
// The detach state defines whether a thread will be defined joinable or
|
||||
// detached.
|
||||
//
|
||||
// <Pthread function declarations>=
|
||||
enum {
|
||||
PTHREAD_CREATE_JOINABLE,
|
||||
PTHREAD_CREATE_DETACHED
|
||||
};
|
||||
|
||||
int pthread_attr_getdetachstate(const pthread_attr_t * attr, int * state);
|
||||
int pthread_attr_setdetachstate(pthread_attr_t * attr, int state);
|
||||
// The stack size defines how much stack space will be allocated. Stack overflows
|
||||
// typically lead to utterly nasty crashes.
|
||||
//
|
||||
// <Pthread function declarations>=
|
||||
int pthread_attr_getstacksize(const pthread_attr_t * attr, size_t * size);
|
||||
int pthread_attr_setstacksize(pthread_attr_t * attr, size_t size);
|
||||
// \section{Creation and Destruction of PThreads}
|
||||
//
|
||||
// First, we define wrapper to map the different calling conventions of Pthreads
|
||||
// and Macintosh threads.
|
||||
//
|
||||
// <Pthread function declarations>=
|
||||
__BEGIN_DECLS
|
||||
typedef void * (*GUSIPThreadProc)(void *);
|
||||
__END_DECLS
|
||||
// [[pthread_create]] stuffs the arguments in a [[CreateArg]] and creates the
|
||||
// context.
|
||||
//
|
||||
// <Pthread function declarations>=
|
||||
int pthread_create(
|
||||
pthread_t * thread,
|
||||
const pthread_attr_t * attr, GUSIPThreadProc proc, void * arg);
|
||||
// A thread can either be detached, in which case it will just go away after it's
|
||||
// done, or it can be joinable, in which case it will wait for [[pthread_join]]
|
||||
// to be called.
|
||||
//
|
||||
// <Pthread function declarations>=
|
||||
int pthread_detach(pthread_t thread);
|
||||
// [[pthread_join]] waits for the thread to die and optionally returns its last
|
||||
// words.
|
||||
//
|
||||
// <Pthread function declarations>=
|
||||
int pthread_join(pthread_t thread, void **value);
|
||||
// [[pthread_exit]] ends the existence of a thread.
|
||||
//
|
||||
// <Pthread function declarations>=
|
||||
int pthread_exit(void *value);
|
||||
// \section{Pthread thread specific data}
|
||||
//
|
||||
// Thread specific data offers a possibility to quickly look up a value that may be
|
||||
// different for every thread.
|
||||
//
|
||||
// [[pthread_key_create]] creates an unique key visible to all threads in a
|
||||
// process.
|
||||
//
|
||||
// <Pthread function declarations>=
|
||||
__BEGIN_DECLS
|
||||
typedef void (*GUSIPThreadKeyDestructor)(void *);
|
||||
__END_DECLS
|
||||
|
||||
int pthread_key_create(pthread_key_t * key, GUSIPThreadKeyDestructor destructor);
|
||||
// [[pthread_key_delete]] deletes a key, but does not call any destructors.
|
||||
//
|
||||
// <Pthread function declarations>=
|
||||
int pthread_key_delete(pthread_key_t key);
|
||||
// [[pthread_getspecific]] returns the thread specific value for a key.
|
||||
//
|
||||
// <Pthread function declarations>=
|
||||
void * pthread_getspecific(pthread_key_t key);
|
||||
// [[pthread_setspecific]] sets a new thread specific value for a key.
|
||||
//
|
||||
// <Pthread function declarations>=
|
||||
int pthread_setspecific(pthread_key_t key, void * value);
|
||||
// \section{Synchronization mechanisms of PThreads}
|
||||
//
|
||||
// Since we're only dealing with cooperative threads, all synchronization
|
||||
// mechanisms can be implemented using means that might look naive to a student
|
||||
// of computer science, but that actually work perfectly well in our case.
|
||||
//
|
||||
// We currently don't support mutex and condition variable attributes. To minimize
|
||||
// the amount of code changes necessary inclients, we support creating and destroying
|
||||
// them, at least.
|
||||
//
|
||||
// <Pthread function declarations>=
|
||||
int pthread_mutexattr_init(pthread_mutexattr_t * attr);
|
||||
int pthread_mutexattr_destroy(pthread_mutexattr_t * attr);
|
||||
// <Pthread function declarations>=
|
||||
int pthread_mutex_init(pthread_mutex_t * mutex, const pthread_mutexattr_t *);
|
||||
int pthread_mutex_destroy(pthread_mutex_t * mutex);
|
||||
// Lock may create the queue if it was allocated statically. Mutexes are implemented
|
||||
// as a queue of context, with the frontmost context holding the lock. Simple enough,
|
||||
// isn't it?
|
||||
//
|
||||
// <Pthread function declarations>=
|
||||
int pthread_mutex_lock(pthread_mutex_t * mutex);
|
||||
// Strangely enough, [[pthread_mutex_trylock]] is much more of a problem if we want
|
||||
// to maintain a semblance of scheduling fairness. In particular, we need the [[Yield]]
|
||||
// in case somebody checks a mutex in a loop with no other yield point.
|
||||
//
|
||||
// <Pthread function declarations>=
|
||||
int pthread_mutex_trylock(pthread_mutex_t * mutex);
|
||||
// Unlocking pops us off the queue and wakes up the new lock owner.
|
||||
//
|
||||
// <Pthread function declarations>=
|
||||
int pthread_mutex_unlock(pthread_mutex_t * mutex);
|
||||
// On to condition variable attributes, which we don't really support either.
|
||||
//
|
||||
// <Pthread function declarations>=
|
||||
int pthread_condattr_init(pthread_condattr_t * attr);
|
||||
int pthread_condattr_destroy(pthread_condattr_t * attr);
|
||||
// Condition variables in some respects work very similar to mutexes.
|
||||
//
|
||||
// <Pthread function declarations>=
|
||||
int pthread_cond_init(pthread_cond_t * cond, const pthread_condattr_t *);
|
||||
int pthread_cond_destroy(pthread_cond_t * cond);
|
||||
// [[pthread_cond_wait]] releases the mutex, sleeps on the condition variable,
|
||||
// and reacquires the mutex.
|
||||
//
|
||||
// <Pthread function declarations>=
|
||||
int pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex);
|
||||
// [[pthread_cond_timedwait]] adds a timeout value (But it still could block
|
||||
// indefinitely trying to reacquire the mutex). Note that the timeout specifies
|
||||
// an absolute wakeup time, not an interval.
|
||||
//
|
||||
// <Pthread function declarations>=
|
||||
int pthread_cond_timedwait(
|
||||
pthread_cond_t * cond, pthread_mutex_t * mutex,
|
||||
const struct timespec * patience);
|
||||
// [[pthread_cond_signal]] wakes up a context from the queue. Since we typically
|
||||
// still hold the associated mutex, it would be a bad idea (though not a disastrous
|
||||
// one) to put a yield in here.
|
||||
//
|
||||
// <Pthread function declarations>=
|
||||
int pthread_cond_signal(pthread_cond_t * cond);
|
||||
// [[pthread_cond_broadcast]] wakes up a the entire queue (but only one context
|
||||
// will get the mutex).
|
||||
//
|
||||
// <Pthread function declarations>=
|
||||
int pthread_cond_broadcast(pthread_cond_t * cond);
|
||||
// \section{Pthread varia}
|
||||
//
|
||||
// [[pthread_self]] returns the current thread.
|
||||
//
|
||||
// <Pthread function declarations>=
|
||||
pthread_t pthread_self(void);
|
||||
// [[pthread_equal]] compares two thread handles.
|
||||
//
|
||||
// <Pthread function declarations>=
|
||||
int pthread_equal(pthread_t t1, pthread_t t2);
|
||||
// [[pthread_once]] calls a routines, guaranteeing that it will be called exactly
|
||||
// once per process.
|
||||
//
|
||||
// <Pthread function declarations>=
|
||||
__BEGIN_DECLS
|
||||
typedef void (*GUSIPThreadOnceProc)(void);
|
||||
__END_DECLS
|
||||
|
||||
int pthread_once(pthread_once_t * once_block, GUSIPThreadOnceProc proc);
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _PTHREAD_H_ */
|
|
@ -1,16 +0,0 @@
|
|||
// <sched.h>=
|
||||
#ifndef _SCHED_H_
|
||||
#define _SCHED_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
/* Required by UNIX 98 */
|
||||
#include <sys/time.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
// [[sched_yield]] yields the processor for other runnable threads.
|
||||
//
|
||||
// <Sched function declarations>=
|
||||
int sched_yield();
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _SCHED_H_ */
|
|
@ -1,75 +0,0 @@
|
|||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* [¤3 Deleted as of 22Jul99, see
|
||||
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
|
||||
* for details]
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)signal.h 8.3 (Berkeley) 3/30/94
|
||||
*/
|
||||
|
||||
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
|
||||
|
||||
#ifndef _USER_SIGNAL_H
|
||||
#define _USER_SIGNAL_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/signal.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
|
||||
extern const char *const sys_signame[NSIG];
|
||||
#endif
|
||||
|
||||
__BEGIN_DECLS
|
||||
int raise __P((int));
|
||||
#ifndef _ANSI_SOURCE
|
||||
int kill __P((pid_t, int));
|
||||
int sigaction __P((int, const struct sigaction *, struct sigaction *));
|
||||
int sigaddset __P((sigset_t *, int));
|
||||
int sigdelset __P((sigset_t *, int));
|
||||
int sigemptyset __P((sigset_t *));
|
||||
int sigfillset __P((sigset_t *));
|
||||
int sigismember __P((const sigset_t *, int));
|
||||
int sigpending __P((sigset_t *));
|
||||
int sigprocmask __P((int, const sigset_t *, sigset_t *));
|
||||
int sigsuspend __P((const sigset_t *));
|
||||
int pthread_kill __P((pthread_t, int));
|
||||
int pthread_sigmask __P((int, const sigset_t *, sigset_t *));
|
||||
int sigwait __P((const sigset_t *, int *));
|
||||
#endif /* !_ANSI_SOURCE */
|
||||
__END_DECLS
|
||||
|
||||
/* List definitions after function declarations, or Reiser cpp gets upset. */
|
||||
#define sigaddset(set, signo) (*(set) |= 1 << ((signo) - 1), 0)
|
||||
#define sigdelset(set, signo) (*(set) &= ~(1 << ((signo) - 1)), 0)
|
||||
#define sigemptyset(set) (*(set) = 0, 0)
|
||||
#define sigfillset(set) (*(set) = ~(sigset_t)0, 0)
|
||||
#define sigismember(set, signo) ((*(set) & (1 << ((signo) - 1))) != 0)
|
||||
|
||||
#endif /* !_USER_SIGNAL_H */
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Berkeley Software Design, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* [¤3 Deleted as of 22Jul99, see
|
||||
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
|
||||
* for details]
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)cdefs.h 8.7 (Berkeley) 1/21/94
|
||||
*/
|
||||
|
||||
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
|
||||
|
||||
#ifndef _CDEFS_H_
|
||||
#define _CDEFS_H_
|
||||
|
||||
#if defined(__cplusplus)
|
||||
#define __BEGIN_DECLS extern "C" {
|
||||
#define __END_DECLS }
|
||||
#else
|
||||
#define __BEGIN_DECLS
|
||||
#define __END_DECLS
|
||||
#endif
|
||||
|
||||
#define __P(x) x
|
||||
|
||||
#endif /* !_CDEFS_H_ */
|
|
@ -1,127 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1982, 1986, 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
* (c) UNIX System Laboratories, Inc.
|
||||
* All or some portions of this file are derived from material licensed
|
||||
* to the University of California by American Telephone and Telegraph
|
||||
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
|
||||
* the permission of UNIX System Laboratories, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* [¤3 Deleted as of 22Jul99, see
|
||||
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
|
||||
* for details]
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)errno.h 8.5 (Berkeley) 1/21/94
|
||||
*/
|
||||
|
||||
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
|
||||
|
||||
#define EPERM 1 /* Operation not permitted */
|
||||
#define ENOENT 2 /* No such file or directory */
|
||||
#define ESRCH 3 /* No such process */
|
||||
#define EINTR 4 /* Interrupted system call */
|
||||
#define EIO 5 /* Input/output error */
|
||||
#define ENXIO 6 /* Device not configured */
|
||||
#define E2BIG 7 /* Argument list too long */
|
||||
#define ENOEXEC 8 /* Exec format error */
|
||||
#define EBADF 9 /* Bad file descriptor */
|
||||
#define ECHILD 10 /* No child processes */
|
||||
#define EDEADLK 11 /* Resource deadlock avoided */
|
||||
/* 11 was EAGAIN */
|
||||
#define ENOMEM 12 /* Cannot allocate memory */
|
||||
#define EACCES 13 /* Permission denied */
|
||||
#define EFAULT 14 /* Bad address */
|
||||
#define ECANCELED 15 /* Operation cancelled */
|
||||
#define EBUSY 16 /* Device busy */
|
||||
#define EEXIST 17 /* File exists */
|
||||
#define EXDEV 18 /* Cross-device link */
|
||||
#define ENODEV 19 /* Operation not supported by device */
|
||||
#define ENOTDIR 20 /* Not a directory */
|
||||
#define EISDIR 21 /* Is a directory */
|
||||
#define EINVAL 22 /* Invalid argument */
|
||||
#define ENFILE 23 /* Too many open files in system */
|
||||
#define EMFILE 24 /* Too many open files */
|
||||
#define ENOTTY 25 /* Inappropriate ioctl for device */
|
||||
#define EFBIG 27 /* File too large */
|
||||
#define ENOSPC 28 /* No space left on device */
|
||||
#define ESPIPE 29 /* Illegal seek */
|
||||
#define EROFS 30 /* Read-only file system */
|
||||
#define EMLINK 31 /* Too many links */
|
||||
#define EPIPE 32 /* Broken pipe */
|
||||
|
||||
/* math software */
|
||||
#define EDOM 33 /* Numerical argument out of domain */
|
||||
#define ERANGE 34 /* Result too large */
|
||||
|
||||
/* non-blocking and interrupt i/o */
|
||||
#define EAGAIN 35 /* Resource temporarily unavailable */
|
||||
#define EWOULDBLOCK EAGAIN /* Operation would block */
|
||||
#define EINPROGRESS 36 /* Operation now in progress */
|
||||
#define EALREADY 37 /* Operation already in progress */
|
||||
|
||||
/* ipc/network software -- argument errors */
|
||||
#define ENOTSOCK 38 /* Socket operation on non-socket */
|
||||
#define EDESTADDRREQ 39 /* Destination address required */
|
||||
#define EMSGSIZE 40 /* Message too long */
|
||||
#define EPROTOTYPE 41 /* Protocol wrong type for socket */
|
||||
#define ENOPROTOOPT 42 /* Protocol not available */
|
||||
#define EPROTONOSUPPORT 43 /* Protocol not supported */
|
||||
#define ESOCKTNOSUPPORT 44 /* Socket type not supported */
|
||||
#define EOPNOTSUPP 45 /* Operation not supported */
|
||||
#define EPFNOSUPPORT 46 /* Protocol family not supported */
|
||||
#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */
|
||||
#define EADDRINUSE 48 /* Address already in use */
|
||||
#define EADDRNOTAVAIL 49 /* Can't assign requested address */
|
||||
|
||||
/* ipc/network software -- operational errors */
|
||||
#define ENETDOWN 50 /* Network is down */
|
||||
#define ENETUNREACH 51 /* Network is unreachable */
|
||||
#define ENETRESET 52 /* Network dropped connection on reset */
|
||||
#define ECONNABORTED 53 /* Software caused connection abort */
|
||||
#define ECONNRESET 54 /* Connection reset by peer */
|
||||
#define ENOBUFS 55 /* No buffer space available */
|
||||
#define EISCONN 56 /* Socket is already connected */
|
||||
#define ENOTCONN 57 /* Socket is not connected */
|
||||
#define ESHUTDOWN 58 /* Can't send after socket shutdown */
|
||||
#define ETOOMANYREFS 59 /* Too many references: can't splice */
|
||||
#define ETIMEDOUT 60 /* Operation timed out */
|
||||
#define ECONNREFUSED 61 /* Connection refused */
|
||||
|
||||
#define ELOOP 62 /* Too many levels of symbolic links */
|
||||
#define ENAMETOOLONG 63 /* File name too long */
|
||||
|
||||
/* should be rearranged */
|
||||
#define EHOSTDOWN 64 /* Host is down */
|
||||
#define EHOSTUNREACH 65 /* No route to host */
|
||||
#define ENOTEMPTY 66 /* Directory not empty */
|
||||
|
||||
#define ENOLCK 77 /* No locks available */
|
||||
#define ENOSYS 78 /* Function not implemented */
|
||||
|
||||
#ifndef _POSIX_SOURCE
|
||||
#define ELOOK 67 /* Internal mapping for kOTLookErr, don't return to client */
|
||||
#define ELAST 78 /* Must be equal largest errno */
|
||||
#endif /* _POSIX_SOURCE */
|
|
@ -1,56 +0,0 @@
|
|||
/*-
|
||||
* Copyright (c) 1982, 1986, 1990, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
* (c) UNIX System Laboratories, Inc.
|
||||
* All or some portions of this file are derived from material licensed
|
||||
* to the University of California by American Telephone and Telegraph
|
||||
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
|
||||
* the permission of UNIX System Laboratories, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* [¤3 Deleted as of 22Jul99, see
|
||||
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
|
||||
* for details]
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)filio.h 8.1 (Berkeley) 3/28/94
|
||||
*/
|
||||
|
||||
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
|
||||
|
||||
#ifndef _SYS_FILIO_H_
|
||||
#define _SYS_FILIO_H_
|
||||
|
||||
#include <sys/ioccom.h>
|
||||
|
||||
/* Generic file-descriptor ioctl's. */
|
||||
#define FIOCLEX _IO('f', 1) /* set close on exec on fd */
|
||||
#define FIONCLEX _IO('f', 2) /* remove close on exec */
|
||||
#define FIONREAD _IOR('f', 127, int) /* get # bytes to read */
|
||||
#define FIONBIO _IOW('f', 126, int) /* set/clear non-blocking i/o */
|
||||
#define FIOASYNC _IOW('f', 125, int) /* set/clear async i/o */
|
||||
#define FIOSETOWN _IOW('f', 124, int) /* set owner */
|
||||
#define FIOGETOWN _IOR('f', 123, int) /* get owner */
|
||||
|
||||
#endif /* !_SYS_FILIO_H_ */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue