pax_global_header 0000666 0000000 0000000 00000000064 12647431132 0014515 g ustar 00root root 0000000 0000000 52 comment=436820d3652ee9f29d16b0268445b5a6b4192698
gap-io-4.4.5+ds/ 0000775 0000000 0000000 00000000000 12647431132 0013305 5 ustar 00root root 0000000 0000000 gap-io-4.4.5+ds/CHANGES 0000664 0000000 0000000 00000016221 12647431132 0014302 0 ustar 00root root 0000000 0000000 This file describes changes in the IO package.
4.4.5 (2016-01-07)
- Move website to http://gap-packages.github.io/io/
- Change IO_PipeThroughWithError to also return the exit status of
the child process
- Improve test suite a little bit
- GAP 4.8 also provides ChangeDirectoryCurrent, so we only
define it if it does not already exist
- Don't wait for child processes to exit on GAP exit
4.4.4 (2014-11-19)
- Fix a bug in the IO_Write code, which for example could cause
IO_WriteLine to fail for certain long string
4.4.3 (2014-11-08)
- Tweak the build system to avoid potential issues when the source
code gets repackages by third parties (e.g. by the GAP team, when
creating their big package archives)
4.4.2 (2014-10-02)
- Recompress tst/test.txt with 'gzip --no-name'
- Fix package name in manual title ("io" -> "IO")
4.4.1 (2014-09-25)
- Fix the release archive (it extracted to a directory starting with
"IO" instead of "io")
4.4 (2014-09-24)
- Fix problem with IO_Pickling some very large objects
- Add pickle support for transformations and partial
permutations
- Try to ensure files are flushed on exit, even if they are
not explicitly closed.
- Ensure file buffers are flushed before GAP closes, to
avoid data loss when files are not closed before exiting.
- Add = and < methods for IsFile objects
- Update Max Neunhoeffer's contact data
- Use AutoDoc to generate title page of the manual from PackageInfo.g
- Add Max Horn as a maintainer
4.3.1 (2014-04-04)
- Previous release had an invalid release date in
PackageInfo.g (2014-04-31 instead of 2014-03-31).
- Merge HISTORY and CHANGES files.
4.3 (2014-03-31)
- Update and tweak the package build system
- Move package repository and website to GitHub
- Pickling/Unpickling of Floats
4.2 (2012-05-28)
- Fix behaviour of IO_select to try again if the system call was
interrupted. This fixes an infinite loop bug in
ParTakeFirstResultByFork.
- Change "source" to "." in AC_FIND_GAP to provide support for BSD.
- Add script "configure_like_gap"
- Compile documentation against 4.5.4
- Fix installations instructions, remove static linking from README.
4.1 (2012-01-30)
- Make it compile on Windows.
4.0 (2012-01-27)
- Use new build setup using automake/autoconf/libtool
- Move repository to git@git.gap-system.org/io
- Updated the documentation of IO_select
3.3 (2011-03-23)
- Fixed a bug to compile on latest cygwin without warning.
- Added IOHub functionality and documented it.
- Hashserver example.
- Cleanup autoconf configuration.
3.2 (2011-02-02)
- Remove the global function f which was accidentally put in there
in 3.1.
- Update cnf files for clang and to compile on GAP 4.4 and 4.5
- Update cnf files to autoconf 2.65
- Add functions gethostname and getsockname.
- Change license to GPL 3
3.1 (2010-07-23)
- Fix documentation of /dev/random and /dev/urandom
- Background jobs
- Parallel patterns: ParMapReduce, ParTakeFirstResult, ParDo
3.0 (2009-04-08)
- Added ignoring of SIGPIPE for architectures where standard
behaviour is to terminate the process.
- Completely new configure process with our own autoconf scripts
- IO_gettimeofday new
- IO_gmtime and IO_localtime new
- Check for IO_getpid and IO_getppid and IO_kill
- Load dynamic module earlier (in init.g at the beginning)
- Release revision 342 as 3.0: 8.4.2009
2.3 (2007-10-03)
- Require GAP >= 4.4.9 in PackageInfo.g
- Change addresses to St Andrews.
- Add understanding of chunked transfer encoding.
- Make IO compile on FreeBSD.
- Added IO_getpid, IO_getppid, IO_kill.
- Change license to GPL V2 or later.
- Released revision 328 as 2.3: 3.10.2007
2.2 (2007-04-02)
- Fixed a serious bug with the generic object pickler.
- Released version 296 as 2.2: 2.4.2007
2.1 (2007-02-26)
- Fixed bug with IO_stat, that time stamps are usually >= 2^28.
- Add framework for other packages to install picklers and unpicklers
even if they are loaded before the IO package.
- Pickling/Unpickling of functions and operations (methods still a problem)
- Leave out last argument of IO_GenericObjectUnpickler because it
was never needed, return either IO_Error or unpickled object. This
changes the semantics!
- Pickling/Unpickling of WeakPointerObjects
- Pickling/Unpickling of permutation groups (including Size and base of
StabChain)
- Pickling/Unpickling of matrix groups (only generators and Size)
- Pickling/Unpickling of finite fields
- Set Host component of HTTP request header by default of the name
of the server argument in SingleHTTPRequest.
- Alexander Konovalov's CheckForUpdates function.
- Released revision 289 as 2.1: 26.2.2007
2.0 (2006-12-12)
- See to SIGCHLD signal handler in Popen, Popen2, and Popen3
- WaitPid in PipeThrough*
- Loop around IO_select calls to ignore EINTR error
- Sort out __stack_chk_fail_local gcc 4.1 problem
- case insensitivity in header field names in HTTP protocol
- fix bug that crashed GAP when starting another process or terminating
GAP after calling Popen*
- Added http protocol test.
- Add tst/platform.g to have a check of "standard things"
- include more headers with #include
- take care of PIPE_BUF variable (might not exist on platform!)
- Improved installation instructions in the manual and the README file.
- Add proper preface to the manual
- Fix documentation of Popen*
- Clean up code for Popen, create IO_ForkExecWithFDs
- IO_StartPipeline
- IO_StringFilterFile, IO_FileFilterString
- paths to executables do PATH lookups using IO_FindExecutable
- IO_FilteredFile to create a File object which filteres through a pipeline.
- Let IO_Close automatically call IO_WaitPid under certain circumstances.
- Released revision 238 as 2.0: 12.12.2006
1.6 (2006-11-16)
- New binding IO_fcntl with corresponding constants in IO
(this is necessary for switching a file descriptor to O_NONBLOCK)
- In IO_WriteNonBlocking only try to send PIPE_BUF bytes instead
of full buffer to avoid blocking (is this the solution?)
- Functionality to pipe a string through an external command
using I/O multiplexing
- New client side HTTP protocol implementation
- Use chapters in documentation
- New functions IO_PipeThrough and IO_PipeThroughWithError to pipe
a string through a process.
- Released version 1.6: 16.11.2006
1.5 (??)
- Big changes in the buffered I/O functionality to allow for non-blocking
I/O with buffers. Documented all. This changed the interface to buffered
I/O considerable!
- Test code for buffered I/O.
- Test code for pickling/unpickling.
- Some small bug fixes of bugs found during development of test code.
1.4 (??)
- moved real random sources from the orb package here
adjust them to new library code
- implement picklers/unpicklers for random sources
1.3 (2006-09-01)
- hint to load a package if there is no handler for magic during unpickling
- follow Frank's suggestion to allow more than one package with a
C-part to be linked to a statically compiled GAP, document this
- release subversion revision 155 as Version 1.3
1.2 (??)
- ?
1.1 (??)
- ?
1.0 (??)
- Initial release
gap-io-4.4.5+ds/GPL 0000664 0000000 0000000 00000104513 12647431132 0013656 0 ustar 00root root 0000000 0000000 GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Copyright (C)
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
.
gap-io-4.4.5+ds/LICENSE 0000664 0000000 0000000 00000001233 12647431132 0014311 0 ustar 00root root 0000000 0000000 This IO package is
Copyright (C) by Max Neunhöffer
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
gap-io-4.4.5+ds/Makefile.am 0000664 0000000 0000000 00000001315 12647431132 0015341 0 ustar 00root root 0000000 0000000 ACLOCAL_AMFLAGS = -I m4
BINARCHDIR = bin/$(GAPARCH)
GAPINSTALLLIB = $(BINARCHDIR)/io.so
lib_LTLIBRARIES = io.la
io_la_SOURCES = src/io.c
io_la_CPPFLAGS = $(GAP_CPPFLAGS) -DCONFIG_H
# Note that the latter is only for GAP 4.4.12
io_la_LDFLAGS = -module -avoid-version
if SYS_IS_CYGWIN
io_la_LDFLAGS += -no-undefined -version-info 0:0:0 -Wl,$(GAPROOT)/bin/$(GAPARCH)/gap.dll
endif
all-local: $(GAPINSTALLLIB)
$(GAPINSTALLLIB): io.la
$(mkdir_p) $(top_srcdir)/$(BINARCHDIR)
if SYS_IS_CYGWIN
cp .libs/io.dll $(GAPINSTALLLIB)
else
cp .libs/io.so $(GAPINSTALLLIB)
endif
clean-local:
rm -f $(GAPINSTALLLIB)
distclean-local:
rm -rf bin/*
(cd doc ; ./clean)
doc:
($(GAPROOT)/bin/gap.sh -A makedoc.g)
.PHONY: doc
gap-io-4.4.5+ds/PackageInfo.g 0000664 0000000 0000000 00000011154 12647431132 0015626 0 ustar 00root root 0000000 0000000 #############################################################################
##
## PackageInfo.g for the package `IO'
##
SetPackageInfo( rec(
PackageName := "IO",
Subtitle := "Bindings for low level C library I/O routines",
Version := "4.4.5",
Date := "07/01/2016", # dd/mm/yyyy format
## Information about authors and maintainers.
Persons := [
rec(
LastName := "Neunhöffer",
FirstNames := "Max",
IsAuthor := true,
IsMaintainer := false,
Email := "max@9hoeffer.de",
WWWHome := "http://www-groups.mcs.st-and.ac.uk/~neunhoef",
PostalAddress := Concatenation( [
"Gustav-Freytag-Straße 40\n",
"50354 Hürth\n",
"Germany" ] ),
#Place := "St Andrews",
#Institution := "University of St Andrews"
),
rec(
LastName := "Horn",
FirstNames := "Max",
IsAuthor := false,
IsMaintainer := true,
Email := "max.horn@math.uni-giessen.de",
WWWHome := "http://www.quendi.de/math",
PostalAddress := Concatenation(
"AG Algebra\n",
"Mathematisches Institut\n",
"Justus-Liebig-Universität Gießen\n",
"Arndtstraße 2\n",
"35392 Gießen\n",
"Germany" ),
Place := "Gießen",
Institution := "Justus-Liebig-Universität Gießen"
),
],
## Status information. Currently the following cases are recognized:
## "accepted" for successfully refereed packages
## "deposited" for packages for which the GAP developers agreed
## to distribute them with the core GAP system
## "dev" for development versions of packages
## "other" for all other packages
##
# Status := "accepted",
Status := "deposited",
## You must provide the next two entries if and only if the status is
## "accepted" because is was successfully refereed:
# format: 'name (place)'
# CommunicatedBy := "Mike Atkinson (St. Andrews)",
#CommunicatedBy := "",
# format: mm/yyyy
# AcceptDate := "08/1999",
#AcceptDate := "",
PackageWWWHome := "http://gap-packages.github.io/io/",
README_URL := Concatenation(~.PackageWWWHome, "README"),
PackageInfoURL := Concatenation(~.PackageWWWHome, "PackageInfo.g"),
ArchiveURL := Concatenation("https://github.com/gap-packages/io/",
"releases/download/v", ~.Version,
"/io-", ~.Version),
ArchiveFormats := ".tar.gz .tar.bz2",
## Here you must provide a short abstract explaining the package content
## in HTML format (used on the package overview Web page) and an URL
## for a Webpage with more detailed information about the package
## (not more than a few lines, less is ok):
## Please, use 'GAP' and
## 'MyPKG' for specifing package names.
##
AbstractHTML :=
"The IO package, as its name suggests, \
provides bindings for GAP to the lower \
levels of Input/Output functionality in the C library.",
PackageDoc := rec(
BookName := "IO",
ArchiveURLSubset := ["doc"],
HTMLStart := "doc/chap0.html",
PDFFile := "doc/manual.pdf",
SixFile := "doc/manual.six",
LongTitle := "Bindings for low level C library I/O routines",
),
Dependencies := rec(
GAP := ">=4.7.4",
NeededOtherPackages := [["GAPDoc", ">= 1.2"]],
SuggestedOtherPackages := [],
ExternalConditions := []
),
AvailabilityTest := function()
if (not("io" in SHOW_STAT())) and
(Filename(DirectoriesPackagePrograms("io"), "io.so") = fail) then
#Info(InfoWarning, 1, "IO: kernel IO functions not available.");
return fail;
fi;
return true;
end,
## *Optional*, but recommended: path relative to package root to a file which
## contains as many tests of the package functionality as sensible.
#TestFile := "tst/testall.g",
## *Optional*: Here you can list some keyword related to the topic
## of the package.
Keywords := ["input", "output", "I/O", "C-library", "network", "http",
"object serialisation", "unpredictable random numbers", "TCP/IP",
"inter process communication", "background jobs", "parallel skeletons",
"I/O multiplexing" ],
AutoDoc := rec(
TitlePage := rec(
Copyright := Concatenation(
"©right; 2005-2014 by Max Neunhöffer\n",
"\n",
"This package may be distributed under the terms and conditions of the\n",
"GNU Public License Version 3 or later.\n"
),
)
),
));
gap-io-4.4.5+ds/README 0000664 0000000 0000000 00000004703 12647431132 0014171 0 ustar 00root root 0000000 0000000
=========================================================
README file for the `IO' GAP4 package (Max Neunhoeffer)
=========================================================
To get the newest version of this GAP 4 package download the
archive file
io-x.x.tar.gz
or
io-x.x.tar.bz2
or
io-x.x.zip
and unpack it using
gunzip io-x.x.tar.gz; tar xvf io-x.x.tar
or
bzip2 -d io-x.x.tar.bz2; tar xvf io-x.x.tar
or
unzip -x io-x.x.zip
respectively.
Do this in a directory called 'pkg', preferably (but not necessarily)
in the 'pkg' subdirectory of your GAP 4 installation. It creates a
subdirectory called 'io'.
To install this package do
cd io
./configure
If you installed io in another directory than the usual 'pkg'
subdirectory, do
./configure --with-gaproot=path
where 'path' is a path to the main GAP root directory.
See
./configure --help
for further options.
Afterwards call 'make' to compile a binary file.
The package will not work without this step.
If you installed the package in another 'pkg' directory than the standard
'pkg' directory in your GAP 4 installation, then you have to add the path
to the directory containing your 'pkg' directory to GAP's list of directories.
This can be done by starting GAP with the '-l' command line option
followed by the name of the directory and a semicolon. Then your directory
is prepended to the list of directories searched. Otherwise the package
is not found by GAP. Of course, you can add this option to your GAP
startup script.
If you installed GAP on several architectures, you must execute the
configure/make step for each of the architectures. You can either
do this immediately after configuring and compiling GAP itself on
this architecture, or alternatively (when using version 4.5 of GAP or
newer) set the environment variable "CONFIGNAME" to the name of the
configuration you used when compiling GAP before running "./configure".
Note however that your compiler choice and flags (environment variables
"CC" and "CFLAGS" need to be chosen to match the setup of the original
GAP compilation. For example you have to specify 32-bit or 64-bit mode
correctly!
----------------------------------------------------------------------------
Recompiling the documentation is possible by the command `gap makedoc.g'
in the IO directory. But this should not be necessary.
For bug reports, feature requests and suggestions, please refer to
https://github.com/gap-packages/io/issues
gap-io-4.4.5+ds/TODO 0000664 0000000 0000000 00000002324 12647431132 0013776 0 ustar 00root root 0000000 0000000 function()
  local v;
  v := IO_gettimeofday();
  return v.tv_sec+0.000001_l*v.tv_usec;
end;
for Laurent
IO_Gettimeofday() returning an integer with the microseconds
and
IO_Gettimeofday_float() returning a float in seconds
with your warning in the documentation
also in Nanoseconds...
-> problem: probably need librt for new timing function
Implement posix_openpt, grantpt, unlockpt and ptsname
to allow usage of pseudo ttys
Later:
See Mail Laurent Feb 02 2011
--> partially done
HTTP access scheint nicht immer zu funktionieren --> debug
offenbar warte ich bei nicht ang. contentlength fuer immer
(ev. nur bei "chunked access"???)
--> www.tagesschau.de z.B.
HTTP/1.1-Konformitaet -> Alexander Konovalovs Tests mit Online int seq site
chunked transfer
Web-Proxy???
Seek fuer File s?
Runtimes() zaehlt children nicht mit???
Ausgabe der Testdateien aussagekraeftiger
??? access to utime/utimes?
More tests?
More examples?
For every release:
Fix "platform.g" test with latest additions.
fix permissions in checked out files
(far) future:
support routines for http requests? (query strings, MIME?)
Maybe a function to change buffer size later on?
Unicode?
gap-io-4.4.5+ds/VERSION 0000664 0000000 0000000 00000000005 12647431132 0014350 0 ustar 00root root 0000000 0000000 4.4.5 gap-io-4.4.5+ds/autogen.sh 0000775 0000000 0000000 00000000055 12647431132 0015306 0 ustar 00root root 0000000 0000000 #!/bin/sh -ex
autoreconf -vif `dirname "$0"`
gap-io-4.4.5+ds/configure.ac 0000664 0000000 0000000 00000004032 12647431132 0015572 0 ustar 00root root 0000000 0000000 AC_PREREQ([2.68])
AC_INIT([io], m4_esyscmd([tr -d '\n' < VERSION]), [https://github.com/gap-packages/io/issues], [io], [http://gap-packages.github.io/io/])
AC_CONFIG_SRCDIR([src/io.c])
AC_CONFIG_HEADER([src/pkgconfig.h:cnf/pkgconfig.h.in])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_AUX_DIR([cnf])
AM_INIT_AUTOMAKE([1.11 -Wall foreign subdir-objects])
AM_SILENT_RULES([yes])
dnl Disable maintainer mode by default. This avoids troubles during packaging,
dnl in particular when the GAP team repackages the source archive.
dnl Users can re-enable it by passing "--enable-maintainer-mode" to configure.
AM_MAINTAINER_MODE
AC_PROG_CC
AM_PROG_AR
LT_PREREQ([2.4.2])
LT_INIT([disable-static dlopen win32-dll])
## Find out what the best compiler flags are
AX_CC_MAXOPT
AC_FIND_GAP
AC_CHECK_SIZEOF([void **])
# Checks for libraries.
# Checks for header files.
AC_HEADER_DIRENT
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS([fcntl.h netdb.h netinet/in.h netinet/tcp.h stdlib.h sys/socket.h sys/time.h time.h unistd.h signal.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_PID_T
AC_CHECK_MEMBERS([struct stat.st_blksize])
AC_STRUCT_ST_BLOCKS
AC_CHECK_MEMBERS([struct stat.st_rdev])
AC_HEADER_TIME
# Checks for library functions.
AC_FUNC_CHOWN
AC_FUNC_CLOSEDIR_VOID
AC_FUNC_FORK
AC_FUNC_LSTAT
AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK
AC_FUNC_SELECT_ARGTYPES
AC_TYPE_SIGNAL
AC_FUNC_STAT
AC_CHECK_FUNCS([dup2 gethostbyname lchown memset mkdir mkfifo rmdir select socket getprotobyname signal sigaction opendir readdir closedir rewinddir telldir seekdir unlink link rename symlink readlink accept bind chmod connect dup fchmod fchown stat fstat lstat getsockopt listen lstat mknod recv recvfrom send sendto setsockopt gettimeofday gmtime localtime getpid getppid kill gethostname getsockname])
AC_CYGWIN
AM_CONDITIONAL([SYS_IS_CYGWIN], [test "$CYGWIN" = "yes"])
if test "$CYGWIN" = "yes"; then
AC_DEFINE(SYS_IS_CYGWIN32, 1, are we on CYGWIN?)
else
AC_DEFINE(SYS_IS_CYGWIN32, 0, are we on CYGWIN?)
fi
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
gap-io-4.4.5+ds/doc/ 0000775 0000000 0000000 00000000000 12647431132 0014052 5 ustar 00root root 0000000 0000000 gap-io-4.4.5+ds/doc/clean 0000775 0000000 0000000 00000000143 12647431132 0015060 0 ustar 00root root 0000000 0000000 #!/bin/bash
rm -f *.{aux,lab,log,dvi,ps,pdf,bbl,ilg,ind,idx,out,html,tex,pnr,txt,blg,toc,six,brf}
gap-io-4.4.5+ds/doc/io.xml 0000664 0000000 0000000 00000002424 12647431132 0015205 0 ustar 00root root 0000000 0000000
<#Include SYSTEM "title.xml">
<#Include SYSTEM "main.xml">
gap-io-4.4.5+ds/doc/main.xml 0000664 0000000 0000000 00000364754 12647431132 0015543 0 ustar 00root root 0000000 0000000
Preface
IO
The purpose of this package is to allow efficient and flexible input/output
operations from &GAP;. This is achieved by providing bindings to the
low-level I/O functions in the C-library. On top of this an implementation
of buffered I/O in the &GAP; language is provided. Further, a framework
for serialisation of arbitrary &GAP; objects is implemented.
Finally, an implementation of the client side of the HTTP protocol is
included in the package.
This package allows to use file based I/O, access to links and file
systems, pipes, sockets, and the UDP and TCP/IP protocols.
By default the IO package is not automatically loaded
by &GAP; when it is installed. You must load the package
with LoadPackage("IO"); before its functions become
available.
For bug reports, feature requests and suggestions, please use our
https://github.com/neunhoef/io/issues.
Installation of the IO-package
To get the newest version of this &GAP; 4 package download one of the
archive files
- io-x.x.tar.gz
- io-x.x.tar.bz2
- io-x.x.zip
and unpack it using
gunzip io-x.x.tar.gz; tar xvf io-x.x.tar
or
bzip2 -d io-x.x.tar.bz2; tar xvf io-x.x.tar
or
unzip -x io-x.x.zip
respectively.
Do this in a directory called pkg
, preferably (but not necessarily)
in the pkg
subdirectory of your &GAP; 4 installation. It creates a
subdirectory called io
.
The package will not work without the following compilation step.
To compile the C part of the package do (in the pkg directory)
cd io
./configure
make
If you installed the package in another pkg
directory than
the standard pkg
directory in your &GAP; 4 installation,
then you have to do two things. Firstly during compilation
you have to use the option
--with-gaproot=PATH of the configure script
where PATH
is a path to the main &GAP; root directory
(if not given the
default ../..
is assumed).
Secondly you have to
specify the path to the directory containing your
pkg
directory to &GAP;'s list of directories. This can be done by starting
&GAP; with the -l
command line option followed by the name
of the directory and a semicolon. Then your directory is prepended to
the list of directories searched. Otherwise the package is not found by
&GAP;. Of course, you can add this option to your &GAP; startup script.
If you installed &GAP; on several architectures, you must execute the
configure/make step for each of the architectures. You can either
do this immediately after configuring and compiling &GAP; itself on
this architecture, or alternatively (when using version 4.5 of &GAP; or
newer) set the environment variable
CONFIGNAME to the name of the configuration you used when
compiling &GAP; before running ./configure.
Note however that your compiler choice and flags
(environment variables CC and CFLAGS) need to be
chosen to match the setup of the original &GAP; compilation. For
example you have to specify 32-bit or 64-bit mode correctly!
Recompiling the documentation
Recompiling the documentation is possible by the command gap
makedoc.g
in the io directory. But this should not be necessary.
Functions directly available from the C library
The following functions from the C library are made available as
&GAP; functions:
accept,
bind,
chdir,
chmod,
chown,
close,
closedir,
connect,
creat,
dup,
dup2,
execv,
execve,
execvp,
exit,
fchmod,
fchown,
fcntl,
fork,
fstat,
gethostbyname,
gethostname,
getpid,
getppid,
getsockname,
getsockopt,
gettimeofday,
gmtime,
kill,
lchown,
link,
listen,
localtime,
lseek,
lstat,
mkdir,
mkfifo,
mknod,
open,
opendir,
pipe,
read,
readdir,
readlink,
recv,
recvfrom,
rename,
rewinddir,
rmdir,
seekdir,
select,
send,
sendto,
setsockopt,
socket,
stat,
symlink,
telldir,
unlink,
write.
Use the man command in your shell to get information about these
functions.
For each of these functions there is a corresponding &GAP; global function
with the prefix IO&uscore; before its name. Apart from minor differences
(see below) they take exactly the same arguments as their C
counterparts. Strings must be specified as &GAP; strings and integers
as &GAP; immediate integers. Return values are in general the same as
for the C counterparts. However, an error condition is indicated by the
value fail instead of -1, and if the result can only be success
or failure, true indicates success.
All errors are reported via the function.
In the C library a lot of integers are defined as macros in header files.
All the necessary values for the above functions are bound to their name
in the global IO record.
Warning: Existence of many of these functions and constants
is platform dependent. The compilation process checks existence and
this leads to the situation that on the &GAP; levels the functions
and constants are there or not. If you want to develop platform
independent &GAP; code using this package, then you have to check
for existence of the functions and constants you need.
Differences in arguments - an overview
The open function has to be called with three arguments. The
version with two arguments is not available on the &GAP; level.
The read function takes four arguments: fd is an integer
file descriptor, st is a &GAP; string, offset is an offset
within this string (zero based), and count is the maximal number
of bytes to read. The data is read and stored into the string st,
starting at position offset+1. The string st is
made long enough, such that count bytes would fit into it, beginning
at position offset+1. The number of bytes read is returned
or fail in case of an error.
The write function is similar, it also takes four arguments:
fd is an integer file descriptor, st is a &GAP; string,
offset is an offset within this string (zero based), and
count is the number of bytes to write, starting from position
offset+1 in the string st. The number of bytes
written is returned, or a fail in case of an error.
The opendir function only returns true or fail.
The readdir function takes no argument. It reads the directory that
was specified in the last call to opendir. It just returns a string,
which is the name of a file or subdirectory in the corresponding directory.
It returns false after the last file name in the directory or
fail in case of an error.
The closedir function takes no argument. It should be called after
readdir returned false or fail to avoid excessive
use of file descriptors.
The functions stat, fstat, and lstat only take one
argument and return a &GAP; record that has the same entries as
a struct stat.
The function socket can optionally take a string as third argument.
In that case it automatically calls getprotobyname to look up the
protocol name.
The functions bind and connect take only one string argument
as address field, because the string already encodes the length.
There are two convenience functions and
to create such addresses. The first takes
two arguments addr and port, where addr is
a string of length 4, containing the 4 bytes of the IP address and
port is a port number as &GAP; integer. The function
takes the same arguments, but the first can
be a string containing an IP address in dot notation like
137.226.152.77
or a hostname to be looked up.
The setsockopt function has no argument optlen. The length
of the string optval is taken.
The select function works as the function UNIXSelect in the
&GAP; library.
As of now, the file locking mechanisms of fcntl using
struct flock are not yet implemented on the &GAP; level.
The low-level functions in detail
Nearly all of this functions return an integer result in the C library.
On the &GAP; level this is either returned as a non-negative integer
in case of success or as fail in case of an error (where on the
C level -1 would be returned). If the integer can only be 0
for no error
this is changed to true on the &GAP; level.
an integer or fail
Accepts an incoming network connection.
For details see man 2 accept
. The argument addr can be
made with and contains its length such
that no third argument is necessary.
an integer or fail
Binds a local address to a socket.
For details see man 2 bind
. The argument
my&uscore;addr can be made with
and contains its length such that no third argument is necessary.
true or fail
Changes the current working directory.
For details see man 2 chdir
.
true or fail
Changes the mode of a file.
For details see man 2 chmod
.
true or fail
Sets owner and/or group of file.
For details see man 2 chown
.
true or fail
Closes a file descriptor.
For details see man 2 close
.
true or fail
Closes a directory.
For details see man 3 closedir
. Has no arguments, because we only
have one DIR struct in the C part.
true or fail
Connects to a remote socket.
For details see man 2 connect
. The argument
serv&uscore;addr can be made with
and contains its length such that no third argument is necessary.
an integer or fail
Creates a new file. For details see man 2 creat
.
an integer or fail
Duplicates a file descriptor.
For details see man 2 dup
.
true or fail
Duplicates a file descriptor to a new one.
For details see man 2 dup2
.
fail or does not return
Replaces the process with another process.
For details see man 3 execv
. The argument argv is a list
of strings. The called program does not have to be the first argument
in this list.
fail or does not return
Replaces the process with another process.
For details see man 3 execve
. The arguments argv and
envp are both lists of strings. The called program does not have to
be the first argument in argv. The list envp can be made
with from a record acquired from and modified later.
fail or does not return
Replaces the process with another process.
For details see man 3 execvp
. The argument argv is a list
of strings. The called program does not have to be the first argument
in this list.
Stops process immediately with return code status.
For details see man 2 exit
. The argument status must
be an integer. Does not return.
true or fail
Changes mode of an opened file.
For details see man 2 fchmod
.
true or fail
Changes owner and/or group of an opened file.
For details see man 2 fchown
.
an integer or fail
Does various things to control the behaviour of a file descriptor.
For details see man 2 fcntl
.
an integer or fail
Forks off a child process, which is an identical copy.
For details see man 2 fork
. Note that if you want to use the
function to wait or check for the termination of
child processes, you have to activate the SIGCHLD handler for this
package beforehand by using the function . Note further that after that you cannot use
the function
any more, since its SIGCHLD handler does not work any more. To switch
back to that functionality use the function .
a record or fail
Returns the file meta data for an opened file.
For details see man 2 fstat
. A &GAP; record is returned with
the same entries than a struct stat.
a record or fail
Return host information by name.
For details see man 3 gethostbyname
. A &GAP; record is returned
with all the relevant information about the host.
a string or fail
Return host name.
For details see man 3 gethostname
.
an integer
Returns the process ID of the current process as an integer. For
details see man 2 getpid
.
an integer
Returns the process ID of the parent of the current process as an
integer. For details see man 2 getppid
.
a string or fail
Get a socket name. For details see man 2 getsockname
.
true or false
Get a socket option. For details see man 2 getsockopt
.
Note that the argument optval carries its length around, such that
no 5th argument is necessary.
A record with components tv_sec and tv_usec
This returns the time elapsed since 1.1.1970, 0:00 GMT. The component
tv_sec contains the number of full seconds and the number
tv_usec the additional microseconds.
A record
The argument is the number of seconds that have elapsed since
1.1.1970, 0:00 GMT. The result is a record with the current Greenwich
mean time
broken down into date and time as in the C-library function
gmtime.
true or fail
Sends the signal sig to the process with process ID
pid. For details see man 2 kill
.
The signal numbers available can be found in the global
IO record with names like SIGTERM.
true or false
Changes owner and/or group of a file not following links.
For details see man 2 lchown
.
true or false
Create a hard link.
For details see man 2 link
.
true or false
Switch a socket to listening.
For details see man 2 listen
.
A record
The argument is the number of seconds that have elapsed since
1.1.1970, 0:00 GMT. The result is a record with the current local time
broken down into date and time as in the C-library function
localtime.
an integer or fail
Seeks within an open file.
For details see man 2 lseek
.
a record or fail
Returns the file meta data for a file not following links.
For details see man 2 lstat
. A &GAP; record is returned with
the same entries than a struct stat.
true or false
Creates a directory.
For details see man 2 mkdir
.
true or false
Creates a FIFO special file (a named pipe).
For details see man 3 mkfifo
.
true or false
Create a special or ordinary file.
For details see man 2 mknod
.
an integer or fail
Open and possibly create a file or device.
For details see man 2 open
. Only the variant with 3 arguments
can be used.
true or false
Opens a directory.
For details see man 3 opendir
. Note that only true is
returned if everything is OK, since only one DIR struct is
stored on the C level and thus only one directory can be open at any
time.
a record or fail
Create a pair of file descriptors with a pipe between them.
For details see man 2 pipe
. Note that no arguments are needed. The
result is either fail in case of an error or a record with two
components toread and towrite bound to the two
filedescriptors for reading and writing respectively.
an integer or fail
Reads from file descriptor.
For details see man 2 read
. Note that there is one more argument
offset to specify at which position in the string st the
read data should be stored. Note that offset zero means at the
beginning of the string, which is position 1 in &GAP;. The number of bytes
read or fail in case of an error is returned.
a string or fail or false
Reads from a directory.
For details see man 2 readdir
. Note that no argument is required
as we have only one DIR struct on the C level. If the directory
is read completely false is returned, and otherwise a string. An
error is indicated by fail.
an integer or fail
Reads the value of a symbolic link.
For details see man 2 readlink
. buf is modified.
The new length of buf is returned or fail in case of
an error.
an integer or fail
Receives data from a socket.
For details see man 2 recv
. Note the additional argument
offset which plays the same role as for the
function.
an integer or fail
Receives data from a socket with given address.
For details see man 2 recvfrom
. Note the additional argument
offset which plays the same role as for the
function. The argument addr can be
made with and contains its length such
that no 7th argument is necessary.
true or false
Renames a file or moves it.
For details see man 2 rename
.
true or fail
Rewinds a directory.
For details see man 2 rewinddir
. Note that no argument is required
as we have only one DIR struct on the C level. Returns fail
only, if no prior command has been called.
true or fail
Removes an empty directory.
For details see man 2 rmdir
.
true or fail
Sets the position of the next readdir call.
For details see man 3 seekdir
. Note that no second argument is
required as we have only one DIR struct on the C level.
an integer or fail
Used for I/O multiplexing.
For details see man 2 select
. inlist, outlist and
exclist are lists of filedescriptors, which are modified. If the
corresponding file descriptor is not yet ready, it is replaced by
fail. The timeout values timeoutsec and
timeoutusec correspond to the usual arguments of select,
if both are immediate integers, they are set, otherwise
select is called with no timeout value.
an integer or fail
Sends data to a socket.
For details see man 2 send
. Note that the additional argument
offset specifies the position of the data to send within the
string st. It is zero based, meaning that zero indicates the
start of the string, which is position 1 in &GAP;.
an integer or fail
Sends data to a socket.
For details see man 2 sendto
. Note that the additional argument
offset specifies the position of the data to send within the
string st. It is zero based, meaning that zero indicates the
start of the string, which is position 1 in &GAP;. The argument
addr can be
made with and contains its length such
that no 7th argument is necessary.
true or fail
Sets a socket option.
For details see man 2 setsockopt
. Note that the argument
optval carries its length around, such that
no 5th argument is necessary.
an integer or fail
Creates a socket, an endpoint for communication.
For details see man 2 socket
.
There is one little special: On systems that have getprotobyname
you can pass a string as third argument protocol which is automatically
looked up by getprotobyname.
a record or fail
Returns the file metadata for the file pathname.
For details see man 2 stat
. A &GAP; record is returned with
the same entries than a struct stat.
true or fail
Creates a symbolic link.
For details see man 2 symlink
.
an integer or fail
Return current location in directory.
For details see man 3 telldir
. Note that no second argument is
required as we have only one DIR struct on the C level.
true or fail
Delete a name and possibly the file it refers to.
For details see man 2 unlink
.
a record or fail
Waits for the termination of a child process.
For details see man 2 waitpid
. Returns a &GAP; record
describing PID and exit status. The second argument wait must
be either true or false. In the first case, the call
blocks until new information about a terminated child process is
available. In the second case no such waiting is performed, the
call returns immediately. See .
an integer or fail
Writes to a file descriptor.
For details see man 2 write
. Note that the additional argument
offset specifies the position of the data to send within the
string st. It is zero based, meaning that zero indicates the
start of the string, which is position 1 in &GAP;.
Further C level functions
The following functions do not correspond to functions in the C library,
but are there to provide convenience to use other functions:
a string or fail
Makes a struct sockaddr&uscore;in from IP address and port.
The IP address must be given as a string of length four, containing the
four bytes of an IPv4 address in natural order. The port must be a port
number. Returns a string containing the struct, which can be given to
all functions above having an address argument.
a list of strings
For details see man environ
. Returns the current environment
as a list of strings of the form key=value
.
true or false
Installs our SIGCHLD handler. This functions works as an idempotent. That
is, calling it twice does exactly the same as calling it once. It returns
true when it is called for the first time since then a pointer to
the old signal handler is stored in a global variable.
See .
Restores the original SIGCHLD handler. This function works as an
idempotent.
That is, calling it twice does exactly the same as calling it once. It
returns true when it is called for the first time after calling
. See .
High level functions for buffered I/O
The functions in the previous sections are intended to be a possibility
for direct access to the low level I/O functions in the C library. Thus,
the calling conventions are strictly as in the original.
The functionality described in this section is implemented completely
in the &GAP; language and is intended to provide a good interface
for programming in &GAP;. The fundamental object for I/O on the C library
level is the file descriptor, which is just a non-negative integer
representing an open file of the process. The basic idea is to wrap up
file descriptors in &GAP; objects that do the buffering.
Note that considerable care has been taken to ensure that one can
do I/O multiplexing with buffered I/O. That is, one always has the
possibility to make sure before a read or write operation, that this
read or write operation will not block. This is crucial when one
wants to serve more than one I/O channel from the same (single-threaded)
&GAP; process. This design principle sometimes made it necessary
to have more than one function for a certain operation. Those
functions usually differ in a subtle way with respect to their
blocking behaviour.
One remark applies again to nearly all functions presented here: If an
error is indicated by the returned value fail one can use the
library function to find
out more about the cause of the error. This fact is not mentioned with
every single function.
Types and the creation of File objects
The wrapped file objects are in the following category:
true or false
The category of File objects.
To create objects in this category, one uses the following function:
a File object
The argument fd must be a file descriptor (i.e. an integer)
or -1 (see below).
rbufsize can either be false for
unbuffered reading or an integer buffer size or a string. If it is
an integer, a read buffer of that size is used. If it is a string,
then fd must be -1 and a File object that reads from that string
is created.
wbufsize can either be false for
unbuffered writing or an integer buffer size or a string. If it is
an integer, a write buffer of that size is used. If it is a string,
then fd must be -1 and a File object that appends to that string
is created.
The result of this function is a new File object.
A convenient way to do this for reading or writing of files on disk
is the following function:
a File object or fail
The argument filename must be a string specifying the path name
of the file to work on. mode must also be a string with possible
values r
, w
, or a
, meaning read access, write
access (with creating and truncating), and append access respectively.
If mode is omitted, it defaults to r
. bufsize, if given,
must be a positive integer or false, otherwise it defaults to
IO.DefaultBufSize.
Internally, the
function is used and the result file descriptor is
wrapped using with bufsize
as the buffer size.
The result is either fail in case of an error or a File object
in case of success.
Note that there is a similar function which
also creates a File object but with additional functionality with
respect to a pipeline for filtering. It is described in its section
in Section . There is some more low-level functionality
to acquire open file descriptors. These can be wrapped into File
objects using .
Reading and writing
Once a File object is created, one can use the following
functions on it:
a string or fail
This function reads all data from the file f until the end of file.
The data is returned as a &GAP; string. If the file is already at end of
file, an empty string is returned. If an error occurs, then fail is
returned. Note that you still have to call on the
File object to properly close the file later.
a string or fail
This function gets two arguments, the first argument f must be
a File object and the second argument len must be
a positive integer. The function tries to read len bytes
and returns a string of that length. If and only if the end of file is
reached earlier, fewer bytes are returned. If an error occurs, fail
is returned. Note that this function blocks until either len bytes
are read, or the end of file is reached, or an error occurs. For the case
of pipes or internet connections it is possible that currently no more
data is available, however, by definition the end of file is only reached
after the connection has been closed by the other side!
a string or fail
This function gets exactly one argument, which must be a File object
f. It reads one line of data, where the definition of line is
operating system dependent. The line end character(s) are included in
the result. The function returns a string with the line in case of
success and fail in case of an error. In the
latter case, one can query the error with .
Note that the reading is done via the buffer of f, such that
this function will be quite fast also for large amounts of data.
If the end of file is hit without a line end, the rest of the file
is returned. If the file is already at end of file before the call,
then a string of length 0 is returned. Note that this
is not an error but the standard end of file convention!
a list of strings or fail
This function gets one or two arguments, the first of which must always
be a File object f. It reads lines of data (where the
definition of line is operating system dependent) either until
end of file (without a second argument) or up to max lines
(with a second argument max. A list of strings with the result is
returned, if everything went well and fail oterwise. In the
latter case, one can query the error with .
Note that the reading is done via the buffer of f, such that
this function will be quite fast also for large amounts of data.
If the file is already at the end of file, the function returns
a list of length 0. Note that this is not an error but the standard end of
file convention!
true or false
This function takes one argument f which must be a File
object. It returns true or false according to whether
there is data to read available in the file f. A return value
of true guarantees that the next call to
on that file will succeed without blocking and return at least one
byte or an empty string to indicate the end of file.
a string or fail
The function gets two arguments, the first of which must
be a File object f. The second argument must be a positive
integer. The function reads data
up to len bytes.
A string with the result is returned, if everything
went well and fail otherwise. In the latter case, one can query
the error with .
Note that the reading is done via the buffer of f, such that
this function will be quite fast also for large amounts of data.
If the file is already at the end of the file, the function returns
a string of length 0. Note that this is not an error!
If a previous call to or to
indicated that there is data available to read, then it is guaranteed that
the function does not block and returns at least
one byte if the file is not yet at end of file and an empty string
otherwise.
an integer or fail
This function can get an arbitrary number of arguments, the first of which
must be a File object f. All the other arguments are just
written to f if they are strings. Otherwise, the String
function is called on them and the result is written out to f.
Note that the writing is done buffered. That is, the data is first written
to the buffer and only really written out after the buffer is full or
after the user explicitly calls on f.
The result is either the number of bytes written in case of success or
fail in case of an error. In the latter case the error can be
queried with .
Note that this function blocks until all data is at least written into
the buffer and might block until data can be sent again if the buffer is
full.
an integer or fail
Behaves like but works on a single string
line and sends an (operating system dependent) end of line
string afterwards. Also is called automatically
after the operation, such that one can be sure, that the data is actually
written out after the function has completed.
an integer or fail
Behaves like but works on a list of strings
list and sends an (operating system dependent) end of line
string after each string in the list. Also is
called automatically after the operation, such that one can be sure,
that the data is actually written out after the function has completed.
true or fail
This function gets one argument f, which must be a File
object. It writes out all the data that is in the write buffer. This
is not necessary before the call to the function ,
since that function calls automatically.
However, it is necessary to call after calls to
to be sure that the data is really sent out. The
function returns true if everything goes well and fail
if an error occurs.
Remember that the functions and implicitly call after
they are done.
Note that this function might block until all data is actually written
to the file descriptor.
an integer or fail
This function behaves like followed by a call to
. It returns either the number of bytes written
or fail if an error occurs.
true or false
This function takes one argument f which must be a File
object. It returns true or false according to whether
the file f is ready to write. A return value
of true guarantees that the next call to
on that file will succeed without blocking and accept at least one
byte.
an integer or fail
This function takes four arguments. The first one f must be
a File object, the second st a string, and the arguments
pos and len must be integers, such that positions
pos+1 until pos+len are bound in
st. The function tries to write up to len bytes from
st from position pos+1 to the file f.
If a previous call to or to indicates that f is writable, then it is
guaranteed that the following call to
will not block and accept at least one byte of data. Note that it is not
guaranteed that all len bytes are written. The function returns
the number of bytes written or fail if an error occurs.
true or false
This function takes one argument f which must be a File
object. It returns true or false according to whether
the file f is ready to flush. A return value
of true guarantees that the next call to
on that file will succeed without blocking and flush out at least one
byte. Note that this does not guarantee, that this call succeeds to
flush out the whole content of the buffer!
true, false, or fail
This function takes one argument f which must be a File
object. It tries to write all data in the writing buffer to the file
descriptor. If this succeeds, the function returns true and
false otherwise. If an error occurs, fail is returned.
If a previous call to or indicated that f is flushable, then it is
guaranteed that the following call to
does not block. However, it is not guaranteed that true is returned
from that call.
true or fail
This function closes the File object f after writing all data
in the write buffer out and closing the file descriptor. All buffers are
freed. In case of an error, the function returns fail and otherwise
true. Note that for pipes to other processes this function collects
data about the terminated processes using .
Other functions
an integer
This function returns the real file descriptor that is behind the
File object f.
a string or false
This function gets one argument f which must be a File object
and returns the writing buffer of that File object. This is
necessary for File objects, that are not associated to a
real file descriptor but just collect everything that was written
in their writing buffer. Remember to use this function before closing
the File object.
an integer or fail
This function is the corresponding function to
for buffered file access. It behaves similarly to that function. The
differences are the following: There are four lists of files r,
w, f, and e. They all can contain either integers
(standing for file descriptors) or File objects. The list r
is for checking, whether files or file descriptors are ready to read, the
list w is for checking whether they are ready to write, the
list f is for checking whether they are ready to flush, and
the list e is for checking whether they have exceptions.
For File objects it is always first checked, whether there is either
data available in a reading buffer or space in a writing buffer. If so,
they are immediately reported to be ready (this feature makes the
list of File objects to test for flushability necessary).
For the remaining files and for
all specified file descriptors, the function is
called to get an overview about readiness. The timeout values t1
and t2 are set to zero for immediate returning if one of the
requested buffers were ready.
returns the number of files or file descriptors
that are ready to serve or fail if an error occurs.
The following function is a convenience function for directory access:
a list of strings or fail
This function gets a string containing a path name as single argument
and returns a list of strings that are the names of the files in that
directory, or fail, if an error occurred.
true on success and fail on failure
Changes the current directory. Returns true on success and
fail on failure.
The following function is used to create strings describing a pair of
an IP address and a port number in a binary way. These strings can be
used in connection with the C library functions connect,
bind, recvfrom, and sendto for the arguments
needing such address pairs.
a string
This function gets a string ipstring containing an IP address
in dot notation, i.e. four numbers in the range from 0 to 255 separated
by dots .
, and an integer portnr, which is a port number.
The result is a string of the correct length to be used for the
low level C library functions, wherever IP address port number pairs
are needed. The string ipstring can also be a host name, which
is then looked up using to find the IP
address.
a record or fail
Takes no arguments, uses to get the environment
and returns a record in which the component names are the names of the
environment variables and the values are the values. This can then be
changed and the changed record can be given to
to produce again a list which can be used for as
third argument.
a list of strings
Takes a record as returned by and turns it
into a list of strings as needed by as third
argument.
Inter process communication
fail or the path to an executable
If the path name path contains a slash, this function simply
checks whether the string path refers to an executable file. If so,
path is returned as is. Otherwise, fail is returned.
If the path name path does not contain a slash, all directories
in the environment variable PATH are searched for an executable
with name path. If so, the full path to that executable is
returned, otherwise fail.
This function is used whenever one of the following functions gets an
argument that should refer to an executable.
nothing
Closes all file descriptors except those listed in exceptions, which
must be a list of integers.
a File object or fail
The argument path must refer to an executable file in the sense
of .
Starts a child process using the executable in path
with either stdout or stdin being a pipe. The
argument mode must be either the string r
or the
string w
.
In the first case, the standard output of the
child process will be the writing end of a pipe. A File object
for reading connected to the reading end of the pipe is returned. The
standard input and standard error of the child process will be the same
than the calling &GAP; process.
In the second case, the standard input of the child process will be the
reading end of a pipe. A File object for writing connected to the
writing end of the pipe is returned. The standard output and standard error
of the child process will be the same than the calling &GAP; process.
In case of an error, fail is returned.
The process will usually die, when the pipe is closed, but can also
do so without that. The File object remembers the process ID
of the started process and the function then
calls for it to acquire information about
the terminated process.
Note that activates our SIGCHLD handler (see ).
In either case the File object will have the attribute
ProcessID
set to the process ID of the child process.
a record or fail
The argument path must refer to an executable file in the sense
of .
A new child process is started using the executable in path
The standard input and standard output of it
are pipes. The writing end of the input pipe and the reading end of the
output pipe are returned as File objects bound to two components
stdin
and stdout
(resp.) of the returned record.
This means, you have to write to stdin
and read
from stdout
in the calling &GAP; process.
The standard error of the child process will be
the same as the one of the calling &GAP; process.
Returns fail if an error occurred.
The process will usually die, when one of the pipes is closed. The File
objects remember the process ID of the called process and the function
call to for the stdout object will call
for it to acquire information about the
terminated process.
Note that activates our SIGCHLD handler (see ).
Both File objects will have the attribute ProcessID
set to the process ID of the child process, which will also be bound to
the pid
component of the returned record.
a record or fail
The argument path must refer to an executable file in the sense
of .
A new child process is started using the executable in path
The standard input, standard output, and standard error of it
are pipes. The writing end of the input pipe, the reading end of the
output pipe and the reading end of the error pipe
are returned as File objects bound to two components
stdin
, stdout
, and stderr
(resp.) of the returned record.
This means, you have to write to stdin
and read
from stdout
and stderr
in the calling
&GAP; process.
Returns fail if an error occurred.
The process will usually die, when one of the pipes is closed. All three
File objects will remember the process ID of the newly created
process and the call to the function for the
stdout object will call for it to acquire
information about the terminated child process.
Note that activates our SIGCHLD handler (see ).
All three File objects will have the attribute ProcessID
set to the process ID of the child process, which will also be bound to
the pid
component of the returned record.
a record or fail
The argument progs is a list of pairs, the first entry being a
path to an executable (in the sense of ),
the second an argument list, the argument
infd is an open file descriptor for
reading, outfd is an open file descriptor for writing, both can be
replaced by the string open
in which case a new pipe will
be opened. The argument switcherror
is a boolean indicating whether standard error channels are also
switched to the corresponding output channels.
This function starts up all processes
and connects them with pipes. The input of the first is switched to
infd and the output of the last to outfd.
Returns a record with the following components: pids is a list of
process ids if everything worked. For each process for which
some error occurred the corresponding pid is replaced by fail.
The stdin component is equal to false, or to the file descriptor
of the writing end of the newly created pipe which is connected to the
standard input of the first of the new processes if
infd was open
.
The stdout component is equal to false or to the file
descriptor of the reading end of the newly created pipe which is connected
to the standard output of the last of the new processes if outfd was
open
.
Note that the SIGCHLD handler of the IO package is installed
by this function (see ) and that it
lies in the responsibility of the caller to use
to ask for the status information of all child processes after their
termination.
a string or fail
Reads the file with the name filename, however, a pipeline
is created by the processes described by progs (see ) to filter the content of the file
through the pipeline. The result is put into a &GAP; string and
returned. If something goes wrong, fail is returned.
a string or fail
Writes the content of the string st to the file with the name
filename, however, a pipeline
is created by the processes described by progs (see ) to filter the content of the string
through the pipeline. The result is put into the file. If the boolean
value append is given and equal to true, then the
data will be appended to the already existing file.
If something goes wrong, fail is returned.
a File object or fail
This function is similar to
and behaves nearly
identically. The only difference is that a filtering pipeline is switched
between the file and the File object such that all things read
or written respectively are filtered through this pipeline of processes.
The File object remembers the started processes and upon the
final call to automatically uses the
function to acquire information from the
terminated processes in the pipeline after their termination. This means
that you do not have to call any more after
the call to .
Note that activates our SIGCHLD handler (see ).
The File object will have the attribute
ProcessID
set to the list of process IDs of the child processes.
a File object or fail
This function is a convenience wrapper around
which handles a number of common
compressed file formats transparently, by calling an external program. The
arguments to this function are identical to .
If the extension to filename is one of gz, bz2 or xz, then the file
is transparently compressed/uncompressed using gzip, bzip2 or xz respectively.
If the extension is none of these, then the command behaves identically to
.
Note that as this function calls , it will
activate our SIGCHLD handler (see ).
When compression / decompression is active, the File object will have
the attribute ProcessID
set to the list of process IDs of the
child processes.
This functions uses to write the whole string
st to the File object f. However, this is done
by forking off a child process identical to the calling &GAP; process
that does the sending. The calling &GAP; process returns immediately, even
before anything has been sent away with the result true.
The forked off sender process terminates itself immediately after it
has sent all data away.
The reason for having this function available is the following: If one
uses or to start up
a child process with standard input and standard output being a pipe,
then one usually has the problem, that the child process starts reading
some data, but then wants to write data, before it received all data
coming. If the calling &GAP; process would first try to write all data
and only start to read the output of the
child process after sending away all data,
a deadlock situation would occur.
This is avoided with the forking and backgrounding approach.
Remember to close the writing end of the standard input pipe in the
calling &GAP; process directly after
has returned, because otherwise the child process might not notice that
all data has arrived, because the pipe persists! See the file
popen2.g in the example directory for an example.
Note that with most modern operating systems the forking off of an
identical child process does in fact not mean a duplication of the
total main memory used by both processes, because the operating system
kernel will use copy on write
. However, if a garbage collection
happens to become necessary during the sending of the data in the
forked off sending process, this might trigger doubled memory usage.
a string or fail
Starts the process with the executable given by the file name
cmd (in the sense of ) with
arguments in the argument list
args (a list of strings). The standard input and output of the started
process are connected via pipes to the calling process. The content of
the string input is written to the standard input of the called
process and its standard output is read and returned as a string.
All the necessary I/O multiplexing and non-blocking I/O
to avoid deadlocks is done in this function.
This function properly does to wait for
the termination of the child process but does not restore the
original &GAP; SIGCHLD signal handler
(see ).
a record or fail
Starts the process with the executable given by the file name
cmd (in the sense of )
with arguments in the argument list
args (a list of strings). The standard input, output and error
of the started
process are connected via pipes to the calling process. The content of
the string input is written to the standard input of the called
process and its standard output and error are read and returned as a
record with components out and err, which are strings.
All the necessary I/O multiplexing and non-blocking I/O
to avoid deadlocks is done in this function.
This function properly does to wait for
the termination of the child process but does not restore the
original &GAP; SIGCHLD signal handler
(see ).
The functions returns either fail if an error occurred, or otherwise
a record with components out and err which are bound
to strings containing the full standard output and standard error
of the called process, and status which is the status returned from
the exiting process.
Object serialisation (Pickling)
The idea of object serialisation
is that one wants to store
nearly arbitrary &GAP; objects to disk or transfer them over the network.
To this end, one wants to convert them to a byte stream that is platform
independent and can later be converted back to a copy of the same object
in memory, be it in the same &GAP; process or another one maybe even on
another machine. The main problem here are the vast amount of different
types occurring in &GAP; and the possibly highly self-referential
structure of &GAP; objects.
The IO package contains a framework to implement object
serialisation and implementations for most of the basic data types
in &GAP;. The framework is easily extendible to other types and takes
complete care of self-references and corresponding problems.
It builds upon the buffered I/O functions described in Section
. We start by describing the user interface.
Result objects
The following static objects are used to report about success or
failure of the (un-)pickling operations:
This object is returned if an error occurs.
This object is returned when there
is nothing to return, for example if an unpickler (see ) encounters the end of a file.
This object is returned if everything went well and there is
no other canonical value to return to indicate this.
The only thing you can do with these special values is to compare them
to each other and to other objects.
Pickling and unpickling
IO&uscore;OK or IO&uscore;Error
The argument f must be an open, writable File
object. The object ob can be an arbitrary &GAP; object.
The operation pickles
or serialises
the object
ob and writes the result into the File object
f. If everything is OK, the unique value IO&uscore;OK
is returned and otherwise the unique value IO&uscore;Error.
The resulting byte stream can be read again using the operation
and is platform- and architecture
independent. Especially the question whether a system has
32 bit or 64 bit wide words and the question of endianess
does not matter.
Note that not all of &GAP;'s object types are supported but it
is relatively easy to extend the system. This package supports
in particular boolean values, integers, permutations, rational
numbers, finite field elements, cyclotomics, strings, polynomials,
rational functions,
lists, records, compressed vectors and matrices over finite fields
(objects are uncompressed in the byte stream but recompressed
during unpickling), and straight line programs.
Self-referential objects built from records and lists are handled
correctly and are restored completely with the same self-references
during unpickling.
IO&uscore;Error or a &GAP; object
The argument f must be an open, readable File
object. The operation reads from f and unpickles
the next object. If an error occurs, the unique value
IO&uscore;Error
is returned. If the File
object is at end of file, the value IO&uscore;Nothing is returned.
Note that these two values are not picklable, because of
their special meaning as return values of this operation here.
Nothing
This function clears the pickle cache
. This cache stores all
object pickled in the current recursive call to
and is necessary to handle self-references. Usually it is not
necessary to call this function explicitly. Only in the rare
case (that should not happen) that a pickling or unpickling operation
enters a break loop which is left by the user, the pickle
cache has to be cleared explicitly using this function for
later calls to and
to work!
Extending the pickling framework
The framework can be extended for other &GAP; object types as follows:
For pickling, a method for the operation has
to be installed which does the work. If the object to be pickled has
subobjects, then the first action of the method is to call the function
IO&uscore;AddToPickled with the object as argument. This will put it
into the pickle cache and take care of self-references. Arbitrary
subobjects can then be pickled using recursive calls to the operation
handing down the same File object into
the recursion. The method must either return IO&uscore;Error in case of
an error or IO&uscore;OK if everything goes well. Before returning,
a method that has called IO&uscore;AddToPickled
must call the function IO&uscore;FinalizePickled without
arguments under all circumstances. If this call is missing,
global data for the pickling procedure becomes corrupt!
Every pickling method must first write a 4 byte magic value such that
later during unpickling of the byte stream the right unpickling
method can be called (see below). Then it can write arbitrary data,
however, this data should be platform- and architecture independent, and
it must be possible to unpickle it later without lookahead
.
Pickling methods should usually not go into a break loop, because
after leaving the user has to call
explicitly!
Unpickling is implemented as follows: For every 4 byte magic value
there must be a function bound to that value in the record
IO&uscore;Unpicklers. If the unpickling operation
encounters that magic value, it calls the corresponding unpickling
function. This function just gets one File object as argument.
Since the magic value is already read, it can immediately start
with reading and rebuilding the serialised object in memory. The method
has to take care to restore the object including its type completely.
If an object type has subobjects, the unpickling function has to
first create a skeleton of the object without its subobjects, then
call IO&uscore;AddToUnpickled on this skeleton, before unpickling
subobjects. If things are not done in this order, the handling of
self-references down in the recursion will not work! An unpickling
function that has called IO&uscore;AddToUnpickled at the beginning
has to call IO&uscore;FinalizeUnpickled without arguments before
returning under all circumstances! If this call is missing,
global data for the unpickling procedure becomes corrupt!
Of course, unpickling functions can recursively call
to unpickle subobjects. Apart from this, unpickling functions can use
arbitrary reading functions on the File object. However, they
should only read sequentially and never move the current file position
pointer otherwise. An unpickling function should return the newly
created object or the value IO&uscore;Error if an error occurred.
They should never go into a break loop, because after leaving the user
has to call explicitly!
Perhaps the best way to learn how to extend the framework is to
study the code for the basic &GAP; objects in the file
pkg/io/gap/pickle.gi.
Really random sources
This section describes so called real random sources
. It is an
extension to the library mechanism of random source objects that uses
the devices /dev/random and /dev/urandom available
on Linux systems (and maybe on other operating systems) providing
random numbers that are impossible to predict. The idea is that such
sources of random numbers are useful to produce unpredictable
secret keys for cryptographic applications.
The functions
a real random source object or fail
The first argument r must be the &GAP; filter
IsRealRandomSource and the second either the string
random or the string urandom. A real
random source object is created that draws its random numbers from
the kernel devices /dev/random and /dev/urandom
respectively. Whereas /dev/urandom always provides random
numbers of not guaranteed quality
, the device /dev/random
measures its entropy and produces guaranteed unpredictable numbers.
However, it might block until enough random
events (like
mouse movements) have been accumulated.
A client side implementation of the HTTP protocol
The IO package contains an implementation of the client side
of the HTTP protocol. The basic purpose of this is of course to be
able to download data from web servers from the &GAP; language. However,
the HTTP protocol can perform a much bigger variety of tasks.
Functions for client side HTTP
a record
The first argument hostname must be a string containing the
hostname of the server to connect. The second argument port
must be an integer in the range from 1 to 65535 and
describes the port to connect to on the server.
The function opens a TCP/IP connection to the server and returns
a record conn with the following components:
conn.sock is fail if an error occurs and otherwise
a File object linked to the file descriptor of the
socket. In case of an error, the component conn.errormsg
contains an error message, it is otherwise empty. If everything
went well then the component conn.host is the result from
the host name lookup (see ) and the
component conn.closed is set to false.
No data is sent or received on the socket in this function.
a record
This function performs a complete HTTP request. The first argument must
be a connection record as returned by a successful call to
. The argument method must
be a valid HTTP request method
in form of a string.
The most common will be GET, POST, or HEAD.
The argument uri is a string containing the URI of the
request, which is given in the first line of the request. This will
usually be a relative or absolute path name given to the server.
The argument header must be a &GAP; record. Each bound field
of this record will we transformed into one header line with the
name of the component being the key and the value the value. All
bound values must be strings. The argument body must either
be a string or false. If it is a string, this string is sent
away as the body of the request. If no string or an empty string is
given, no body will be sent. The header field Content-Length
is automatically created from the length of the string body.
Finally, the argument target can either be false or
a string. In the latter case, the body of the request answer
is written to the file with the name given in target. The
body component of the result will be the file name in this
case. If target is false, the full body of the answer is
stored into the body component of the result.
The function sends away the request and awaits the answer. If anything
goes wrong during the transfer (for example if the connection is
broken prematurely), then the component statuscode of the
resulting record is 0 and the component status is
a corresponding error message. In that case, all other fields may
or may not be bound to sensible values, according to when the
error occurred. If everything goes well, then statuscode
and status are bound to the corresponding values coming from
the request answer. statuscode is transformed into a &GAP;
integer. The header of the answer is parsed, transformed into
a &GAP; record, and stored into the component header of the
result. The body component of the result record is set
as described above. Finally, the protoversion component
contains the HTTP protocol version number used by the server as
a string and the boolean value closed indicates, whether
or not the function has detected, that the connection has been
closed by the server. Note that by default, the connection will
stay open, at least for a certain time after the end of the
request.
See the description of the global variable for rules how timeouts are done in
this function.
Note that if the method is HEAD, then no body
is expected (none will be sent anyway) and the function returns
immediately with empty body. Of course, the Content-Length
value in the header is as if it the request would be done with the
GET method.
This global variable holds a list of length two. By default, both entries
are fail indicating that should never
timeout and wait forever for an answer. Actually, the two values in
this variable are given to the function call
during I/O multiplexing. That is, the first number is in seconds and
the second in milliseconds. Together they lead to a timeout for the
HTTP request. If a timeout occurs, an error condition is triggered
which returns a record with status code 0 and status being
the timeout error message.
You can change the timeout by accessing the two entries of this
write protected list variable directly.
nothing
Closes the connection described by the connection record conn.
No error can possibly occur.
a record
The arguments are as the corresponding ones in the functions
and
respectively. This function opens an HTTP connection, tries
a single HTTP request and immediately closes the connection
again. The result is as for the
function. If an error occurs during the opening of the connection,
the statuscode value of the result is 0 and the error
message is stored in the status component of the result.
The previous function allows for a very simple implementation of a
function that checks, whether your current &GAP; installation is
up to date:
nothing
This function accesses a web page in St. Andrews and runs some
&GAP; code from there. This code knows all the currently released
versions of &GAP; and its packages. It prints out a summary and
possibly suggests upgrades. If you do not want to executed
code downloaded from the internet, then do not call this function.
More concretely, the page accessed is
http://www.gap-system.org/Download/upgrade.html and the
code executed is a single call to the function SuggestUpgrades
function in the &GAP; library.
nothing
This function downloads the file from the given uniform resource
locator URL using the HTTP protocol
and reads the contents into &GAP; using
.
Note that this can execute arbitrary code on your machine with the
privileges of the &GAP; job running, so you should be very careful
what files you download and execute. You have been warned!
Background jobs using fork
This chapter describes a way to use multi-processor or multi-core machines
from within &GAP;. In its current version the &GAP; system is a single
threaded and single process system. However, modern operating systems
allow, via the fork system call, to replicate a complete process
on the same machine relatively efficiently. That is, at first after
a fork the two processes actually use the same physical memory
such that not much copying needs to be done. The child process is in
exactly the same state as the parent process, sharing open files, network
connections and the complete status of the workspace. However, whenever
a page of memory is written, it is then automatically copied using new,
additional physical memory, such that it behaves like a completely separate
process. This method is called copy-on-write
.
Thus this is a method to parallelise certain computations. Note however, that
from the point of time when the fork has occurred, all further
communication between the two processes has to be realised via pipes
or even files.
The operations and methods described in this chapter help to use &GAP; in this
way and implement certain skeletons
of parallel programming to
make these readily available in &GAP;. Note that this implementation
has its severe limitations and should probably eventually be replaced
by a proper multi-threaded version of &GAP;.
Background jobs
One creates a background job with the following operation:
a background job object or fail
This operation creates a background job using
which starts up as an identical copy of the currently running &GAP;
process. In this child process the function fun is called
with the argument list args. The third argument opt
must be a record for options. The operation returns either an object
representing the background job or fail if the startup did not
work.
This operation automatically sets up two pipes for communication with
the child process. This is in particular used to report the result of
the function call to fun back to the parent. However, if called
without the option TerminateImmediately (see below) the child
process stays alive even after the completion of fun and one
can submit further argument lists for subsequent calls to fun.
Of course, these additional argument lists will have to be sent
over a pipe to the child process. A special case is if the argument
args is equal to fail, in this case the child process is
started but does not automatically call fun but rather
waits in an idle state until an argument list is submitted via the
pipe using the operation described below.
There are two components defined which can be bound in the options record
opt. One is TerminateImmediately, if this is bound to true
then the child process immediately terminates after the function fun
returns its result. In this case, no pipe for communication from parent
to child is created since it would never be used. Note that in this case
one can still get the result of the function fun using the
operation described below, even when
the child has already terminated, since the result is first transmitted
back to the parent before termination.
The following operations are available to deal with background job
objects:
true, false or fail
This operation checks whether or not the background job represented by
the object job has already finished the function call to its
worker function and is now idle. If so, true is returned. If it
is still running and working on the worker function, false is returned.
If the background job has already terminated altogether, this operation
returns fail. Note that if a child process terminates automatically
after the first completion of its worker function and sending the result,
then the first call to
after completion will return
true to indicate successful completion and all subsequent calls
will return fail.
true or false
This operation checks whether or not the background job represented by
the object job has already terminated.
If so, true is returned, if not, false is returned.
the result of the worker function or fail
This operation waits until the worker function of the background job
job has finished and the job is idle. It then returns the result
of the worker function, which has automatically been transmitted to
the parent process. If the child process has died before completion
fail is returned.
the result of the worker function or fail
This operation does the same as .
true or fail
This submits another argument list args for another call to the
worker function in the background job job. It is an error if
either the background job has already terminated or if it is still busy
working on the previous argument list. That is, one must only submit
another argument in a situation when
would return
true. This is for example the case directly after a successful
call to or i
which did
not return fail, unless the background job was created with the
TerminateImmediately option set to true.
This operation returns immediately after submission, when the new argument
list has been sent to the child process through a pipe. In particular,
it does not await completion of the worker function for the new
argument list.
nothing
This kills the background job represented by the object job
with immediate effect. No more results can be expected from it.
Note that unless one has created the background job with the
TerminateImmediately option set to true one always
has to call on a background job eventually
for cleanup purposes. Otherwise, the background job and the connecting
pipes remain alive until the parent &GAP; process terminates.
Parallel programming skeletons
In this section we document the operations for the available
skeletons. For a general description of these ideas see other
sources.
a list of results or fail
The argument jobs must be a list of &GAP; functions and the
argument args a list of the same length containing argument
lists with which the job functions can be called. This operation
starts up a background job using fork for each of the functions
in jobs, calls it with the corresponding argument list in
args. As soon as any of the background jobs finishes with a result,
terminates all other jobs and
reports the results found so far. Note that it can happen that two
jobs finish at the same time
in the sense that both results
are received before all other jobs could be terminated. Therefore
the result of is a list, in which
position i is bound if and only if job number i returned
a result. So in the result at least one entry is bound but it is possible
that more than one entry is bound.
You can specify an overall timeout to give up the whole computation
if no job finishes by setting the TimeOut component of the
options record opt. In this case you have to set it to
a record with two components tv_sec and tv_usec which
are seconds and microseconds respectively, exactly as returned by the
function. In the case of timeout
an empty list is returned.
a list of results or fail
The argument jobs must be a list of &GAP; functions and the
argument args a list of the same length containing argument
lists with which the job functions can be called. This operation
starts up a background job using fork for each of the functions
in jobs, calls it with the corresponding argument list in
args. As soon as all of the background jobs finish with a result,
reports the results found.
Therefore
the result of is a list, in which
position i is bound to the result that job number i returned.
You can specify an overall timeout to stop the whole computation
if not all jobs finish in time by setting the TimeOut component of the
options record opt. In this case you have to set it to
a record with two components tv_sec and tv_usec which
are seconds and microseconds respectively, exactly as returned by the
function. In the case of timeout
a list is returned in which the positions corresponding to those
jobs that have already finished are bound to the respective results
and the other positions are unbound.
a list of results or fail
This is a parallel version of the
function. It applies the function worker to all elements of
the list l and returns a list containing the results in
corresponding positions. You have to specify the component
NumberJobs in the options record opt which indicates how many
background processes to start. You can optionally use the TimeOut
option exactly as for , however, if a timeout
occurs, returns fail.
Note that the usefulness of this operation is relatively limited, since
every individual result has to be sent back over a pipe from the child process
to the parent process. Therefore this only makes sense if the computation
time for the worker function dominates the communication time.
a value or fail
This is a parallel version implementation of the classical MapReduce
pattern.
It applies the function map to all elements of
the list l and then reduces the result using the reduce function
which accepts two return values of map and returns one of them.
Thus, the final result is one return value or fail if the startup
of the jobs fails. You have to specify the component
NumberJobs in the options record opt which indicates how many
background processes to start. You can optionally use the TimeOut
option exactly as for , however, if a timeout
occurs, returns fail.
Note that this can be very useful because quite often
the cumulated computation time for all the worker function calls
dominates the communication time for a single result.
Note that the next parallel skeleton is a worker farm which
is described in the following section.
Worker farms
The parallel skeleton of a worker farm is basically nothing but
a bunch of background jobs all with the same worker function and
all eagerly waiting for work. The only additional concepts needed
are an input and an output queue. The input queue contains
argument lists and the output queue pairs of argument lists
and results.
One creates a worker farm with the following operation:
an object representing the worker farm or fail
This operation creates a worker farm with the worker function
fun and sets up its input and output queue. An object representing
the farm is returned unless not all jobs could be started up in which
case fail is returned. After startup all background jobs in the
farm are idle. The only valid option in the options record opt
is NumberJobs and it must be bound to the number of worker
jobs in the farm, a positive integer.
The following operations are for worker farm objects:
nothing
This operation called on a worker farm object wf administrates
the input and output queues of the worker farm. In particular it
checks whether new results are available from the workers and if so
it appends them to the output queue. If jobs are idle and the input
queue is non-empty, argument lists from the input queue are sent
to the idle jobs and removed from the input queue.
This operation must be called regularly to keep up the communication
with the clients. It uses select and so does not
block if the boolean argument block is set to false.
However, if larger chunks of data has to be sent or received this
operation might need some time to return.
If the boolean argument block is set to true then the
blocks until at least one job has returned
a result. This can be used to wait for the termination of all tasks
without burning CPU cycles in the parent job. One would repeatedly
call with block set to true
and after each such call check with
whether all tasks are done. Note that one should no longer call
with block set to true once
this is the case since then it would block forever.
This operation is called automatically by most of the following
operations.
nothing
This operation terminates all background jobs in the farm wf,
which cannot be used subsequently. One should always call this operation
when the worker farm is no longer needed to free resources.
true or false
This operation returns true if all background jobs in the
worker farm wf are idle. This means, that all tasks which
have previously been submitted using have
been completed and their result been appended to the output
queue. The operation is automatically
called before the execution of .
nothing
This operation submits a task in the form of an argument list for the
worker function to the worker farm. It is appended at the end of the
input queue.
The operation is automatically
called after the execution of , giving the
farm a chance to actually send the work out to the worker background
jobs.
nothing
This operation collects all results from the output queue of the
worker farm. The output queue is empty after this function returns.
The results are reported as a list of pairs, each pair has the
input argument list as first component and the output object
as second component.
The operation is automatically
called before the execution of , giving the
farm a chance to actually receive some more results from the worker background
jobs.
I/O multiplexing
Introduction
Whenever one needs to do input/output on more than one connection (file
descriptor) at a time, some code is needed to organise the I/O
multiplexing. Due to the single-threaded nature of the current &GAP;
language one has to use and some
buffering and queueing to organise this. This chapter describes a
relative generic implementation of I/O-multiplexing using so-called
objects. The basic idea is that an object handles lots of I/O connections at the same
time and maintains a buffer for each of them. There is a very simple
protocol that marks chunks of data (called messages
) and whenever
a message has been received completely it is collected in the input
queue of the , marked with the number of the
connection it came from. Rather than sending a message away
in one go, one would always schedule it for sending by appending it to
the output queue. The operation , when called often
enough, will then make sure that the message is sent away eventually.
The operations for IOHub objects
In this section, we simply describe the functions and operations
to create, use and destroy objects.
an object
This creates a new object at first without any open
connections.
a positive integer
This operation adds a new connection to the object
h. The arguments i and o must be Unix file
descriptors or 0 and i must be open for reading if
it is positive and o must be open for writing if it is
positive. It is allowed that both file descriptors are equal, but they
may not both be equal to 0. The operation returns a positive
integer which is the number under which this new connection will be
administrated in the object. Note that this number is
specific to the object h.
From the moment these file descriptors are registered with the
object, every subsequent call to will
try to do input and output on them. This means in particular that the
other side of this connection should be in the same initial
state of the protocol. Usually this will be achieved by them being
added as a new connection to a corresponding object on
the other side at the same time.
See also below.
nothing
The argument h must be an object and
nr the number of a connection which was previously returned
by . The corresponding connection is
closed and removed from the .
a Unix file descriptor or fail
The argument h must be an object,
addr an IP address or host name as a string and port a
port number (see also ).
This operation creates a new socket, binds it to the IP
address
and port and attaches it to the object. From
this moment on the operation will accept new
bidirectional TCP/IP connections on that socket and add them to
h. The operation returns either the file descriptor of the
new socket or fail if an error occurred.
nothing
The argument h must be an object.
Any server socket which was attached to h is shut down,
so no new connections will be accepted.
nothing
The argument h must be an object.
All connections of h will be closed using and any serving socket will be
shut down using . The object will not be usable any more after this call.
a positive integer or fail
The argument h must be an object.
The object h must have a serving socket attached to it
via , otherwise fail is
returned and nothing happens. One more connection is accepted through
the serving socket. It is added as a new bidirectional TCP/IP
connection to the object and the new connection
number is returned. Note first that this operation blocks until a new
connection comes in. Note furthermore that this operation is usually
called automatically in whenever a new connection
has come in, which is reported in the internal
call. So usually, the client code does not have to call this operation
at all.
true or fail
The argument h must be an object,
nr must be a positive integer which is the number of
an open connection of h which can be used for output.
The argument st must be a &GAP; string. This operation
appends the message st to the end of the output queue
for the connection nr. Note that at this stage no output
is actually performed automatically. One has to call
subsequently to actually send the message away.
a list of length 2
The argument h must be an object,
nr must be an integer.
If nr is positive, this operation returns the earliest message
which has come in from connection number nr and has not yet been
returned by before. This message is then removed
from the input queue. If there is no such message, then false
is returned. A message is returned as a plain list of length 2
where the first entry is the connection number it came from and
the second entry is a string containing the message itself. If
nr is equal to 0 then the first message in the input
queue from any connection is returned or false if there is no
message in the input queue.
a connection number or fail
The argument h must be an object,
the arguments addr and port must be an address/port
pair as used in , so address
can either be a host name or an IP address and port is a port
number. This operation opens a new TCP connection to the address and
port specified, adds a new bidirectional connection to the
h using
and returns the connection number specific to the object
h. If anything goes wrong, fail is returned.
a list
The argument h must be an object.
This returns the internal object for the output queue. Its elements
are pairs where the first entry is the connection number where it
is going to be sent and the second entry is the message as a string.
Only modify this list if you really know what you are doing.
a list
The argument h must be an object.
This returns the internal object for the input queue. Its elements
are pairs where the first entry is the connection number from where
the message was received and the second entry is the message as a string.
Only modify this list if you really know what you are doing.
true or false or fail
The argument h must be an object,
and the optional second argument block must be true or
false. This operation uses to decide
which of the file descriptors belonging to the connections of h
are ready to read or write. All file descriptors which are ready are
served, possibly updating the input and output queues. A possible
serving socket is also served accepting a new connection if there is one.
The operation loops until no more file
descriptors are ready. It returns true if some I/O was
performed and false if not. It returns fail if the
is already shut down.
The second argument block indicates
whether or not should block until some I/O
has taken place. If this argument is omitted then false
(non-blocking operation) is the default.
Note that broken connections are silently closed.
Examples
There is an example hash server in the file
examples/hashserver.g.
Examples of usage
For larger examples see the example directory of the package.
You find there a small server using the TCP/IP protocol and
a corresponding client and another small server using the UDP protocol
and a corresponding client.
Further, there is an example for the
usage of File objects, that read from or write to strings.
Another example there shows starting up a child process and piping
a few megabytes through it using .
In the following, we present a few explicit, interactive short examples
for the usage of the functions in this package. Note that you have to
load the IO package with the command
LoadPackage("IO");
before trying these examples.
Writing and reading a file
The following sequence of commands opens a file with name guck and
writes some things to it:
gap> f := IO_File("guck","w");
<file fd=3 wbufsize=65536 wdata=0>
gap> IO_Write(f,"Hello world\n");
12
gap> IO_WriteLine(f,"Hello world2!");
14
gap> IO_Write(f,12345);
5
gap> IO_Flush(f);
true
gap> IO_Close(f);
true
There is nothing special about this, the numbers are numbers of bytes
written. Note that only after the command the
data is actually written to disk. Before that, it resides in the
write buffer of the file. Note further, that the
call here would not have been necessary, since the
call flushes the buffer anyway.
The file can again be read with the following sequence of commands:
gap> f := IO_File("guck","r");
<file fd=3 rbufsize=65536 rpos=1 rdata=0>
gap> IO_Read(f,10);
"Hello worl"
gap> IO_ReadLine(f);
"d\n"
gap> IO_ReadLine(f);
"Hello world2!\n"
gap> IO_ReadLine(f);
"12345"
gap> IO_ReadLine(f);
""
gap> IO_Close(f);
true
Note here that reading line-wise can only be done efficiently by using
buffered I/O. You can mix calls to and to
. The end of file is indicated by an empty
string returned by one of the read functions.
Using filtering programs to read and write files
If you want to write a big amount of data to file you might want to compress
it on the fly without using much disk space. This can be achieved with
the following command:
gap> s := "";; for i in [1..10000] do Append(s,String(i)); od;;
gap> Length(s);
38894
gap> IO_FileFilterString("guck.gz",[["gzip",["-9c"]]],s);
true
gap> sgz := StringFile("guck.gz");;
gap> Length(sgz);
18541
gap> ss := IO_StringFilterFile([["gzip",["-dc"]]],"guck.gz");;
gap> s=ss;
true
This sequence of commands needs that the program gzip is installed
on your system.
Using filters when reading or writing files sequentially
If you want to process bigger amounts of data you might not want to
store all of it in a single &GAP; string. In that case you might want
to access a file on disk sequentially through a filter:
gap> f := IO_FilteredFile([["gzip",["-9c"]]],"guck.gz","w");
<file fd=5 wbufsize=65536 wdata=0>
gap> IO_Write(f,"Hello world!\n");
13
gap> IO_Write(f,Elements(SymmetricGroup(5)),"\n");
1359
gap> IO_Close(f);
true
gap> f := IO_FilteredFile([["gzip",["-dc"]]],"guck.gz","r");
<file fd=4 rbufsize=65536 rpos=1 rdata=0>
gap> IO_ReadLine(f);
"Hello world!\n"
gap> s := IO_ReadLine(f);; Length(s);
1359
gap> IO_Read(f,10);
""
gap> IO_Close(f);
true
Accessing a web page
The IO package has an HTTP client implementation. Using this
you can access web pages and other web downloads from within &GAP;. Here
is an example:
gap> r := SingleHTTPRequest("www.math.rwth-aachen.de",80,"GET",
> "/~Max.Neunhoeffer/index.html",rec(),false,false);;
gap> RecFields(r);
[ "protoversion", "statuscode", "status", "header", "body", "closed" ]
gap> r.status;
"OK"
gap> r.statuscode;
200
gap> r.header;
rec( date := "Thu, 07 Dec 2006 22:08:22 GMT",
server := "Apache/2.0.55 (Ubuntu)",
last-modified := "Thu, 16 Nov 2006 00:21:44 GMT",
etag := "\"2179cf-11a5-3c77f600\"", accept-ranges := "bytes",
content-length := "4517", content-type := "text/html; charset=ISO-8859-1" )
gap> Length(r.body);
4517
Of course, the time stamps and exact sizes of the answer may differ
when you do this.
(Un-)Pickling
Assume you have some &GAP; objects you want to archive to disk grouped
together. Then you might do the following:
gap> r := rec( a := 1, b := "Max", c := [1,2,3] );
rec( a := 1, b := "Max", c := [ 1, 2, 3 ] )
gap> r.c[4] := r;
rec( a := 1, b := "Max", c := [ 1, 2, 3, ~ ] )
gap> f := IO_File("guck","w");
<file fd=3 wbufsize=65536 wdata=0>
gap> IO_Pickle(f,r);
IO_OK
gap> IO_Pickle(f,[(1,2,3,4),(3,4)]);
IO_OK
gap> IO_Close(f);
true
Then, to read it in again, just do:
gap> f := IO_File("guck");
<file fd=3 rbufsize=65536 rpos=1 rdata=0>
gap> IO_Unpickle(f);
rec( a := 1, b := "Max", c := [ 1, 2, 3, ~ ] )
gap> IO_Unpickle(f);
[ (1,2,3,4), (3,4) ]
gap> IO_Unpickle(f);
IO_Nothing
gap> IO_Close(f);
true
Note that this works for a certain amount of builtin objects. If you want
to archive your own objects or more sophisticated objects you have to
use extend the functionality as explained in Section
. However, it works for lists and records and
they may be arbitrarily self-referential.
License
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see http://www.gnu.org/licenses/.
gap-io-4.4.5+ds/doc/title.xml 0000664 0000000 0000000 00000002027 12647431132 0015716 0 ustar 00root root 0000000 0000000
IO
Bindings for low level C library I/O routines
4.4.5
Max Neunhöffer
Gustav-Freytag-Straße 40
50354 Hürth
Germany
max@9hoeffer.de
http://www-groups.mcs.st-and.ac.uk/~neunhoef
Max Horn
AG Algebra
Mathematisches Institut
Justus-Liebig-Universität Gießen
Arndtstraße 2
35392 Gießen
Germany
max.horn@math.uni-giessen.de
http://www.quendi.de/math
07/01/2016
©right; 2005-2014 by Max Neunhöffer
This package may be distributed under the terms and conditions of the
GNU Public License Version 3 or later.