/***************************************************************************
**
*A io.c IO-package Max Neunhoeffer
**
**
** Copyright (C) by Max Neunhoeffer
** This file is free software, see license information at the end.
**
*/
// Try to use as much of the GNU C library as possible:
#define _GNU_SOURCE
#include "gap_all.h" // GAP headers
#undef PACKAGE
#undef PACKAGE_BUGREPORT
#undef PACKAGE_NAME
#undef PACKAGE_STRING
#undef PACKAGE_TARNAME
#undef PACKAGE_URL
#undef PACKAGE_VERSION
#include "pkgconfig.h" // our own autoconf results
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_TIME_H
#include <time.h>
#endif
#include <errno.h>
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
#ifdef HAVE_SIGNAL_H
// Maybe the GAP kernel headers have already included it:
#ifndef SYS_SIGNAL_H
#include <signal.h>
#endif
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#if defined (__CYGWIN__) || defined (__CYGWIN32__)
#include <cygwin/in.h>
#endif
/* Functions that are done:
* open, creat, read, write, close, unlink, lseek, opendir, readdir,
* closedir, rewinddir, telldir, seekdir, link, rename, symlink, readlink,
* rmdir, mkdir, stat, lstat, fstat, chmod, fchmod, chown, fchown, lchown,
* mknod, mkstemp, mkdtemp, mkfifo, dup, dup2, socket, bind, connect,
* gethostbyname, listen,
* accept, recv, recvfrom, send, sendto, getsockopt, setsockopt, select,
* fork, execv, execvp, execve, pipe, exit, getsockname, gethostname,
*
* Additional helper functions:
* make_sockaddr_in, MakeEnvList, environ,
*/
/* Functions that are to do (maybe later):
*
* and perhaps:
* socketpair, getsockname, poll, setrlimit, getrlimit, getrusage, ulimit,
* not for the moment (portability or implementation problems):
* remove, scandir, ioctl? (absolutely unportable, as it seems),
* fcntl? (for file locking purposes), recvmsg, sendmsg,
*/
/***********************************************************************
* First we have our own SIGCHLD handler. It is a copy of the one in the
* GAP kernel, however, information about all children that are not
* coming from streams is stored in one data structure here, such that
* we can read it out from GAP using IO.Wait.
***********************************************************************/
// FIXME: globals
#define MAXCHLDS 1024
// The following arrays make a FIFO structure:
static int stats[MAXCHLDS]; // than this number
static int pids[MAXCHLDS]; // and this number!
static int fistats = 0; // First used entry
static int lastats = 0; // First unused entry
static int statsfull = 0; // Flag, whether stats FIFO full
// This function must only be called while IO's signal handler is disabled!
static int findSignaledPid(int pidc)
{
if (fistats == lastats && !statsfull) // queue empty
return -1;
if (pidc == -1) // queue not empty and any entry welcome
return fistats;
int pos = fistats;
while (pids[pos] != pidc) {
pos++;
if (pos >= MAXCHLDS)
pos = 0;
if (pos == lastats) {
pos = -1; // None found
break ;
}
}
return pos;
}
// This function must only be called while IO's signal handler is disabled!
static void removeSignaledPidByPos(int pos)
{
if (fistats == lastats && !statsfull) // queue empty
return ;
int newpos;
if (pos == fistats) { // this is the easy case:
fistats++;
if (fistats >= MAXCHLDS)
fistats = 0;
}
else { // The more difficult case:
do {
newpos = pos + 1;
if (newpos >= MAXCHLDS)
newpos = 0;
if (newpos == lastats)
break ;
stats[pos] = stats[newpos];
pids[pos] = pids[newpos];
pos = newpos;
} while (1);
lastats = pos;
}
statsfull = 0;
}
// This does not have to be the same size as the array above
static int ignoredpids[MAXCHLDS];
static int ignoredpidslen;
static int IO_CheckForIgnoredPid(int pid);
static void (*oldhandler)(int whichsig) = 0; // the old handler
static void IO_HandleChildSignal(int retcode, int status)
{
if (retcode > 0) { // One of our child processes terminated
if (WIFEXITED(status) || WIFSIGNALED(status)) {
#ifdef GAP_HasCheckChildStatusChanged
if (CheckChildStatusChanged(retcode, status)) {
// GAP has dealt with the signal
}
else
#endif
if (IO_CheckForIgnoredPid(retcode)) {
// Previously registered with IO_IgnorePid
}
else if (!statsfull) {
stats[lastats] = status;
pids[lastats++] = retcode;
if (lastats >= MAXCHLDS)
lastats = 0;
if (lastats == fistats)
statsfull = 1;
}
else
Pr("#E Overflow in table of terminated processes\n" , 0, 0);
}
}
}
#ifdef HAVE_SIGNAL
void IO_SIGCHLDHandler(int whichsig)
{
int retcode, status;
// We collect information about our child processes that have terminated
do {
retcode = waitpid(-1, &status, WNOHANG);
IO_HandleChildSignal(retcode, status);
} while (retcode > 0);
signal(SIGCHLD, IO_SIGCHLDHandler);
}
static Obj FuncIO_InstallSIGCHLDHandler(Obj self)
{
// Do not install ourselves twice:
if (oldhandler == 0) {
oldhandler = signal(SIGCHLD, IO_SIGCHLDHandler);
signal(SIGPIPE, SIG_IGN);
return True ;
}
return False ;
}
static Obj FuncIO_RestoreSIGCHLDHandler(Obj self)
{
if (oldhandler == 0)
return False ;
signal(SIGCHLD, oldhandler);
oldhandler = 0;
signal(SIGPIPE, SIG_DFL);
return True ;
}
// The following function checks if a PID is marked as ignored.
// Returns 1 if the PID was ignored, 0 otherwise.
// This function must only be called while IO's signal handler is disabled!
static int IO_CheckForIgnoredPid(int pid)
{
int i;
// Make sure a new signal doesn't come in while looking at array
int found = 0;
for (i = 0; i < ignoredpidslen; ++i) {
if (ignoredpids[i] == pid) {
ignoredpids[i] = ignoredpids[ignoredpidslen - 1];
ignoredpidslen--;
found = 1;
break ;
}
}
return found;
}
static Obj FuncIO_IgnorePid(Obj self, Obj pid)
{
Int pidc;
int pos;
if (!IS_INTOBJ(pid)) {
return Fail;
}
pidc = INT_INTOBJ(pid);
if (pidc < 0) {
return Fail;
}
// Make sure a new signal doesn't come in while we are changing array
signal(SIGCHLD, SIG_DFL);
pos = findSignaledPid(pidc);
if (pos != -1) {
// This PID has already finished
removeSignaledPidByPos(pos);
signal(SIGCHLD, IO_SIGCHLDHandler);
return True ;
}
if (ignoredpidslen < MAXCHLDS - 1) {
ignoredpids[ignoredpidslen] = pidc;
ignoredpidslen++;
signal(SIGCHLD, IO_SIGCHLDHandler);
}
else {
Pr("#E Overflow in table of ignored processes" , 0, 0);
signal(SIGCHLD, IO_SIGCHLDHandler);
return Fail;
}
return True ;
}
static Obj FuncIO_WaitPid(Obj self, Obj pid, Obj wait)
{
Int pidc;
int pos;
Obj tmp;
int retcode, status;
int reallytried;
if (!IS_INTOBJ(pid)) {
SyClearErrorNo();
return Fail;
}
// First set SIGCHLD to default action to avoid clashes with access:
signal(SIGCHLD, SIG_DFL);
pidc = INT_INTOBJ(pid);
reallytried = 0;
do {
pos = findSignaledPid(pidc);
if (pos != -1)
break ; // we found something!
if (reallytried && wait != True ) {
// Reinstantiate our handler:
signal(SIGCHLD, IO_SIGCHLDHandler);
return False ;
}
// Really wait for something
retcode = waitpid(-1, &status, (wait == True ) ? 0 : WNOHANG);
IO_HandleChildSignal(retcode, status);
reallytried = 1; // Do not try again.
} while (1); // Left by break
tmp = NEW_PREC(0);
AssPRec(tmp, RNamName("pid" ), INTOBJ_INT(pids[pos]));
AssPRec(tmp, RNamName("status" ), INTOBJ_INT(stats[pos]));
AssPRec(tmp, RNamName("WIFEXITED" ), INTOBJ_INT(WIFEXITED(stats[pos])));
AssPRec(tmp, RNamName("WEXITSTATUS" ),
INTOBJ_INT(WEXITSTATUS(stats[pos])));
// Dequeue element:
removeSignaledPidByPos(pos);
// Reinstantiate our handler:
signal(SIGCHLD, IO_SIGCHLDHandler);
return tmp;
}
#endif
static Obj FuncIO_open(Obj self, Obj path, Obj flags, Obj mode)
{
int res;
if (!IS_STRING(path) || !IS_STRING_REP(path) || !IS_INTOBJ(flags) ||
!IS_INTOBJ(mode)) {
SyClearErrorNo();
return Fail;
}
res = open(CSTR_STRING(path), INT_INTOBJ(flags), INT_INTOBJ(mode));
if (res < 0) {
SySetErrorNo();
return Fail;
}
return INTOBJ_INT(res);
}
static Obj FuncIO_creat(Obj self, Obj path, Obj mode)
{
int res;
if (!IS_STRING(path) || !IS_STRING_REP(path) || !IS_INTOBJ(mode)) {
SyClearErrorNo();
return Fail;
}
res = creat(CSTR_STRING(path), INT_INTOBJ(mode));
if (res < 0) {
SySetErrorNo();
return Fail;
}
return INTOBJ_INT(res);
}
static Obj FuncIO_read(Obj self, Obj fd, Obj st, Obj offset, Obj count)
{
Int bytes;
Int len;
if (!IS_INTOBJ(fd) || !IS_STRING(st) || !IS_STRING_REP(st) ||
!IS_INTOBJ(count)) {
SyClearErrorNo();
return Fail;
}
len = INT_INTOBJ(offset) + INT_INTOBJ(count);
if (len > GET_LEN_STRING(st))
GrowString(st, len);
bytes = read(INT_INTOBJ(fd), CHARS_STRING(st) + INT_INTOBJ(offset),
INT_INTOBJ(count));
if (bytes < 0) {
SySetErrorNo();
return Fail;
}
if (bytes + INT_INTOBJ(offset) > GET_LEN_STRING(st)) {
SET_LEN_STRING(st, bytes + INT_INTOBJ(offset));
CHARS_STRING(st)[len] = 0;
}
return INTOBJ_INT(bytes);
}
static Obj FuncIO_write(Obj self, Obj fd, Obj st, Obj offset, Obj count)
{
Int bytes;
if (!IS_INTOBJ(fd) || !IS_STRING(st) || !IS_STRING_REP(st) ||
!IS_INTOBJ(offset) || !IS_INTOBJ(count)) {
SyClearErrorNo();
return Fail;
}
if (GET_LEN_STRING(st) < INT_INTOBJ(offset) + INT_INTOBJ(count)) {
SyClearErrorNo();
return Fail;
}
bytes = (Int )write(INT_INTOBJ(fd), CHARS_STRING(st) + INT_INTOBJ(offset),
INT_INTOBJ(count));
if (bytes < 0) {
SySetErrorNo();
return Fail;
}
return INTOBJ_INT(bytes);
}
static Obj FuncIO_close(Obj self, Obj fd)
{
int res;
if (!IS_INTOBJ(fd)) {
SyClearErrorNo();
return Fail;
}
res = close(INT_INTOBJ(fd));
if (res < 0) {
SySetErrorNo();
return Fail;
}
return True ;
}
static Obj FuncIO_lseek(Obj self, Obj fd, Obj offset, Obj whence)
{
Int bytes;
if (!IS_INTOBJ(fd) || !IS_INTOBJ(offset) || !IS_INTOBJ(whence)) {
SyClearErrorNo();
return Fail;
}
bytes = lseek(INT_INTOBJ(fd), INT_INTOBJ(offset), INT_INTOBJ(whence));
if (bytes < 0) {
SySetErrorNo();
return Fail;
}
return INTOBJ_INT(bytes);
}
#ifdef HAVE_DIRENT_H
// FIXME: globals
static DIR * ourDIR = 0;
static struct dirent * ourdirent;
#ifdef HAVE_OPENDIR
static Obj FuncIO_opendir(Obj self, Obj name)
{
if (!IS_STRING(name) || !IS_STRING_REP(name)) {
SyClearErrorNo();
return Fail;
}
ourDIR = opendir(CSTR_STRING(name));
if (ourDIR == 0) {
SySetErrorNo();
return Fail;
}
return True ;
}
#endif // HAVE_OPENDIR
#ifdef HAVE_READDIR
static Obj FuncIO_readdir(Obj self)
{
Int olderrno;
if (ourDIR == 0) {
SyClearErrorNo();
return Fail;
}
olderrno = errno;
ourdirent = readdir(ourDIR);
if (ourdirent == 0) {
// This is a bit of a hack, but how should this be done?
if (errno == EBADF && olderrno != EBADF) {
SySetErrorNo();
return Fail;
}
else {
SyClearErrorNo();
return False ;
}
}
return MakeString(ourdirent->d_name);
}
#endif // HAVE_READDIR
#ifdef HAVE_CLOSEDIR
static Obj FuncIO_closedir(Obj self)
{
int res;
if (ourDIR == 0) {
SyClearErrorNo();
return Fail;
}
res = closedir(ourDIR);
if (res < 0) {
SySetErrorNo();
return Fail;
}
return True ;
}
#endif // HAVE_CLOSEDIR
#ifdef HAVE_REWINDDIR
static Obj FuncIO_rewinddir(Obj self)
{
if (ourDIR == 0) {
SyClearErrorNo();
return Fail;
}
rewinddir(ourDIR);
return True ;
}
#endif // HAVE_REWINDDIR
#ifdef HAVE_TELLDIR
static Obj FuncIO_telldir(Obj self)
{
Int o;
if (ourDIR == 0) {
SyClearErrorNo();
return Fail;
}
o = telldir(ourDIR);
if (o < 0) {
SySetErrorNo();
return Fail;
}
return INTOBJ_INT(o);
}
#endif // HAVE_TELLDIR
#ifdef HAVE_SEEKDIR
static Obj FuncIO_seekdir(Obj self, Obj offset)
{
if (!IS_INTOBJ(offset)) {
SyClearErrorNo();
return Fail;
}
if (ourDIR == 0) {
SyClearErrorNo();
return Fail;
}
seekdir(ourDIR, INT_INTOBJ(offset));
return True ;
}
#endif // HAVE_SEEKDIR
#endif // HAVE_DIRENT_H
#ifdef HAVE_UNLINK
static Obj FuncIO_unlink(Obj self, Obj path)
{
int res;
if (!IS_STRING(path) || !IS_STRING_REP(path)) {
SyClearErrorNo();
return Fail;
}
res = unlink(CSTR_STRING(path));
if (res < 0) {
SySetErrorNo();
return Fail;
}
return True ;
}
#endif
#ifdef HAVE_LINK
static Obj FuncIO_link(Obj self, Obj oldpath, Obj newpath)
{
int res;
if (!IS_STRING(oldpath) || !IS_STRING_REP(oldpath) ||
!IS_STRING(newpath) || !IS_STRING_REP(newpath)) {
SyClearErrorNo();
return Fail;
}
res = link(CSTR_STRING(oldpath), CSTR_STRING(newpath));
if (res < 0) {
SySetErrorNo();
return Fail;
}
return True ;
}
#endif
#ifdef HAVE_RENAME
static Obj FuncIO_rename(Obj self, Obj oldpath, Obj newpath)
{
int res;
if (!IS_STRING(oldpath) || !IS_STRING_REP(oldpath) ||
!IS_STRING(newpath) || !IS_STRING_REP(newpath)) {
SyClearErrorNo();
return Fail;
}
res = rename(CSTR_STRING(oldpath), CSTR_STRING(newpath));
if (res < 0) {
SySetErrorNo();
return Fail;
}
return True ;
}
#endif
#ifdef HAVE_SYMLINK
static Obj FuncIO_symlink(Obj self, Obj oldpath, Obj newpath)
{
int res;
if (!IS_STRING(oldpath) || !IS_STRING_REP(oldpath) ||
!IS_STRING(newpath) || !IS_STRING_REP(newpath)) {
SyClearErrorNo();
return Fail;
}
res = symlink(CSTR_STRING(oldpath), CSTR_STRING(newpath));
if (res < 0) {
SySetErrorNo();
return Fail;
}
return True ;
}
#endif
#ifdef HAVE_READLINK
static Obj FuncIO_readlink(Obj self, Obj path, Obj buf, Obj bufsize)
{
int res;
if (!IS_STRING(path) || !IS_STRING_REP(path) || !IS_STRING(buf) ||
!IS_STRING_REP(buf) || !IS_INTOBJ(bufsize)) {
SyClearErrorNo();
return Fail;
}
GrowString(buf, INT_INTOBJ(bufsize));
res = readlink(CSTR_STRING(path), CSTR_STRING(buf), INT_INTOBJ(bufsize));
if (res < 0) {
SySetErrorNo();
return Fail;
}
SET_LEN_STRING(buf, res);
CHARS_STRING(buf)[res] = 0;
return INTOBJ_INT(res);
}
#endif
static Obj FuncIO_realpath(Obj self, Obj path)
{
if (!IS_STRING_REP(path)) {
SyClearErrorNo();
return Fail;
}
char buf[PATH_MAX];
if (realpath(CSTR_STRING(path), buf)) {
return MakeImmString(buf);
}
SySetErrorNo();
return Fail;
}
static Obj FuncIO_chdir(Obj self, Obj pathname)
{
int res;
if (!IS_STRING(pathname) || !IS_STRING_REP(pathname)) {
SyClearErrorNo();
return Fail;
}
res = chdir(CSTR_STRING(pathname));
if (res < 0) {
SySetErrorNo();
return Fail;
}
return True ;
}
static Obj FuncIO_getcwd(Obj self)
{
char * res;
char buf[GAP_PATH_MAX];
res = getcwd(buf, sizeof (buf));
if (res == NULL) {
SySetErrorNo();
return Fail;
}
return MakeImmString(buf);
}
#ifdef HAVE_MKDIR
static Obj FuncIO_mkdir(Obj self, Obj pathname, Obj mode)
{
int res;
if (!IS_STRING(pathname) || !IS_STRING_REP(pathname) ||
!IS_INTOBJ(mode)) {
SyClearErrorNo();
return Fail;
}
res = mkdir(CSTR_STRING(pathname), INT_INTOBJ(mode));
if (res < 0) {
SySetErrorNo();
return Fail;
}
return True ;
}
#endif
#ifdef HAVE_RMDIR
static Obj FuncIO_rmdir(Obj self, Obj path)
{
int res;
if (!IS_STRING(path) || !IS_STRING_REP(path)) {
SyClearErrorNo();
return Fail;
}
res = rmdir(CSTR_STRING(path));
if (res < 0) {
SySetErrorNo();
return Fail;
}
return True ;
}
#endif
#if defined (HAVE_STAT) || defined (HAVE_FSTAT) || defined (HAVE_LSTAT)
static Obj WrapStat(struct stat * statbuf)
{
Obj rec = NEW_PREC(13);
AssPRec(rec, RNamName("dev" ), ObjInt_UInt8(statbuf->st_dev));
AssPRec(rec, RNamName("ino" ), ObjInt_UInt8(statbuf->st_ino));
AssPRec(rec, RNamName("mode" ), ObjInt_UInt(statbuf->st_mode));
AssPRec(rec, RNamName("nlink" ), ObjInt_UInt8(statbuf->st_nlink));
AssPRec(rec, RNamName("uid" ), ObjInt_UInt(statbuf->st_uid));
AssPRec(rec, RNamName("gid" ), ObjInt_UInt(statbuf->st_gid));
AssPRec(rec, RNamName("rdev" ), ObjInt_UInt8(statbuf->st_rdev));
AssPRec(rec, RNamName("size" ), ObjInt_Int8(statbuf->st_size));
AssPRec(rec, RNamName("blksize" ), ObjInt_Int8(statbuf->st_blksize));
AssPRec(rec, RNamName("blocks" ), ObjInt_Int8(statbuf->st_blocks));
AssPRec(rec, RNamName("atime" ), ObjInt_Int(statbuf->st_atime));
AssPRec(rec, RNamName("mtime" ), ObjInt_Int(statbuf->st_mtime));
AssPRec(rec, RNamName("ctime" ), ObjInt_Int(statbuf->st_ctime));
return rec;
}
#endif
#ifdef HAVE_STAT
static Obj FuncIO_stat(Obj self, Obj filename)
{
if (!IS_STRING(filename) || !IS_STRING_REP(filename)) {
SyClearErrorNo();
return Fail;
}
struct stat ourstatbuf;
int res = stat(CSTR_STRING(filename), &ourstatbuf);
if (res < 0) {
SySetErrorNo();
return Fail;
}
return WrapStat(&ourstatbuf);
}
#endif
#ifdef HAVE_FSTAT
static Obj FuncIO_fstat(Obj self, Obj fd)
{
if (!IS_INTOBJ(fd)) {
SyClearErrorNo();
return Fail;
}
struct stat ourstatbuf;
int res = fstat(INT_INTOBJ(fd), &ourstatbuf);
if (res < 0) {
SySetErrorNo();
return Fail;
}
return WrapStat(&ourstatbuf);
}
#endif
#ifdef HAVE_LSTAT
static Obj FuncIO_lstat(Obj self, Obj filename)
{
if (!IS_STRING(filename) || !IS_STRING_REP(filename)) {
SyClearErrorNo();
return Fail;
}
struct stat ourstatbuf;
int res = lstat(CSTR_STRING(filename), &ourstatbuf);
if (res < 0) {
SySetErrorNo();
return Fail;
}
return WrapStat(&ourstatbuf);
}
#endif
#ifdef HAVE_CHMOD
static Obj FuncIO_chmod(Obj self, Obj pathname, Obj mode)
{
int res;
if (!IS_STRING(pathname) || !IS_STRING_REP(pathname) ||
!IS_INTOBJ(mode)) {
SyClearErrorNo();
return Fail;
}
res = chmod(CSTR_STRING(pathname), INT_INTOBJ(mode));
if (res < 0) {
SySetErrorNo();
return Fail;
}
return True ;
}
#endif
#ifdef HAVE_FCHMOD
static Obj FuncIO_fchmod(Obj self, Obj fd, Obj mode)
{
int res;
if (!IS_INTOBJ(fd) || !IS_INTOBJ(mode)) {
SyClearErrorNo();
return Fail;
}
res = fchmod(INT_INTOBJ(fd), INT_INTOBJ(mode));
if (res < 0) {
SySetErrorNo();
return Fail;
}
return True ;
}
#endif
#ifdef HAVE_CHOWN
static Obj FuncIO_chown(Obj self, Obj path, Obj owner, Obj group)
{
int res;
if (!IS_STRING(path) || !IS_STRING_REP(path) || !IS_INTOBJ(owner) ||
!IS_INTOBJ(group)) {
SyClearErrorNo();
return Fail;
}
res = chown(CSTR_STRING(path), INT_INTOBJ(owner), INT_INTOBJ(group));
if (res < 0) {
SySetErrorNo();
return Fail;
}
return True ;
}
#endif
#ifdef HAVE_FCHOWN
static Obj FuncIO_fchown(Obj self, Obj fd, Obj owner, Obj group)
{
int res;
if (!IS_INTOBJ(fd) || !IS_INTOBJ(owner) || !IS_INTOBJ(group)) {
SyClearErrorNo();
return Fail;
}
res = fchown(INT_INTOBJ(fd), INT_INTOBJ(owner), INT_INTOBJ(group));
if (res < 0) {
SySetErrorNo();
return Fail;
}
return True ;
}
#endif
#ifdef HAVE_LCHOWN
static Obj FuncIO_lchown(Obj self, Obj path, Obj owner, Obj group)
{
int res;
if (!IS_STRING(path) || !IS_STRING_REP(path) || !IS_INTOBJ(owner) ||
!IS_INTOBJ(group)) {
SyClearErrorNo();
return Fail;
}
res = lchown(CSTR_STRING(path), INT_INTOBJ(owner), INT_INTOBJ(group));
if (res < 0) {
SySetErrorNo();
return Fail;
}
return True ;
}
#endif
#ifdef HAVE_MKNOD
static Obj FuncIO_mknod(Obj self, Obj path, Obj mode, Obj dev)
{
int res;
if (!IS_STRING(path) || !IS_STRING_REP(path) || !IS_INTOBJ(mode) ||
!IS_INTOBJ(dev)) {
SyClearErrorNo();
return Fail;
}
res = mknod(CSTR_STRING(path), INT_INTOBJ(mode), INT_INTOBJ(dev));
if (res < 0) {
SySetErrorNo();
return Fail;
}
return True ;
}
#endif
#ifdef HAVE_MKSTEMP
static Obj FuncIO_mkstemp(Obj self, Obj template )
{
Int fd;
if (!IS_STRING(template ) || !IS_STRING_REP(template )) {
SyClearErrorNo();
return Fail;
}
fd = mkstemp(CSTR_STRING(template ));
if (fd < 0) {
SySetErrorNo();
return Fail;
}
return INTOBJ_INT(fd);
}
#endif
#ifdef HAVE_MKDTEMP
static Obj FuncIO_mkdtemp(Obj self, Obj template )
{
char * r;
if (!IS_STRING(template ) || !IS_STRING_REP(template )) {
SyClearErrorNo();
return Fail;
}
r = mkdtemp(CSTR_STRING(template ));
if (r == NULL) {
SySetErrorNo();
return Fail;
}
return MakeString(r);
}
#endif
#ifdef HAVE_MKFIFO
static Obj FuncIO_mkfifo(Obj self, Obj path, Obj mode)
{
int res;
if (!IS_STRING(path) || !IS_STRING_REP(path) || !IS_INTOBJ(mode)) {
SyClearErrorNo();
return Fail;
}
res = mkfifo(CSTR_STRING(path), INT_INTOBJ(mode));
if (res < 0) {
SySetErrorNo();
return Fail;
}
return True ;
}
#endif
#ifdef HAVE_DUP
static Obj FuncIO_dup(Obj self, Obj oldfd)
{
int res;
if (!IS_INTOBJ(oldfd)) {
SyClearErrorNo();
return Fail;
}
res = dup(INT_INTOBJ(oldfd));
if (res < 0) {
SySetErrorNo();
return Fail;
}
return INTOBJ_INT(res);
}
#endif
#ifdef HAVE_DUP2
static Obj FuncIO_dup2(Obj self, Obj oldfd, Obj newfd)
{
int res;
if (!IS_INTOBJ(oldfd) || !IS_INTOBJ(newfd)) {
SyClearErrorNo();
return Fail;
}
res = dup2(INT_INTOBJ(oldfd), INT_INTOBJ(newfd));
if (res < 0) {
SySetErrorNo();
return Fail;
}
return True ;
}
#endif
#ifdef HAVE_SOCKET
static Obj FuncIO_socket(Obj self, Obj domain, Obj type, Obj protocol)
{
int res;
#ifdef HAVE_GETPROTOBYNAME
struct protoent * pe;
#endif
Int proto;
if (!IS_INTOBJ(domain) || !IS_INTOBJ(type) ||
!(IS_INTOBJ(protocol)
#ifdef HAVE_GETPROTOBYNAME
|| (IS_STRING(protocol) && IS_STRING_REP(protocol))
#endif
)) {
SyClearErrorNo();
return Fail;
}
#ifdef HAVE_GETPROTOBYNAME
if (IS_STRING(protocol)) { // we have to look up the protocol
pe = getprotobyname(CSTR_STRING(protocol));
if (pe == NULL) {
SySetErrorNo();
return Fail;
}
proto = pe->p_proto;
}
else
#endif
proto = INT_INTOBJ(protocol);
res = socket(INT_INTOBJ(domain), INT_INTOBJ(type), proto);
if (res < 0) {
SySetErrorNo();
return Fail;
}
return INTOBJ_INT(res);
}
#endif
#ifdef HAVE_BIND
static Obj FuncIO_bind(Obj self, Obj fd, Obj my_addr)
{
int res;
Int len;
if (!IS_INTOBJ(fd) || !IS_STRING(my_addr) || !IS_STRING_REP(my_addr)) {
SyClearErrorNo();
return Fail;
}
len = GET_LEN_STRING(my_addr);
res = bind(INT_INTOBJ(fd), (struct sockaddr *)CHARS_STRING(my_addr), len);
if (res < 0) {
SySetErrorNo();
return Fail;
}
return True ;
}
#endif
#ifdef HAVE_CONNECT
static Obj FuncIO_connect(Obj self, Obj fd, Obj serv_addr)
{
int res;
Int len;
if (!IS_INTOBJ(fd) || !IS_STRING(serv_addr) ||
!IS_STRING_REP(serv_addr)) {
SyClearErrorNo();
return Fail;
}
len = GET_LEN_STRING(serv_addr);
res = connect(INT_INTOBJ(fd),
(struct sockaddr *)(CHARS_STRING(serv_addr)), len);
if (res < 0) {
SySetErrorNo();
return Fail;
}
return True ;
}
#endif
#ifdef HAVE_SOCKET
static Obj FuncIO_make_sockaddr_in(Obj self, Obj ip, Obj port)
{
struct sockaddr_in sa;
if (!IS_INTOBJ(port) || !IS_STRING(ip) || !IS_STRING_REP(ip) ||
GET_LEN_STRING(ip) != 4) {
SyClearErrorNo();
return Fail;
}
memset(&sa, 0, sizeof (sa));
sa.sin_family = AF_INET;
sa.sin_port = htons(INT_INTOBJ(port));
memcpy(&(sa.sin_addr.s_addr), CHARS_STRING(ip), 4);
return MakeStringWithLen((void *)&sa, sizeof (sa));
}
#endif
#ifdef HAVE_GETHOSTBYNAME
static Obj FuncIO_gethostbyname(Obj self, Obj name)
{
struct hostent * he;
Obj res;
Obj tmp;
Obj tmp2;
char ** p;
Int i;
Int len;
if (!IS_STRING(name) || !IS_STRING_REP(name)) {
SyClearErrorNo();
return Fail;
}
he = gethostbyname(CSTR_STRING(name));
if (he == NULL) {
SySetErrorNo();
return Fail;
}
res = NEW_PREC(0);
tmp = MakeString(he->h_name);
AssPRec(res, RNamName("name" ), tmp);
for (len = 0, p = he->h_aliases; *p != NULL; len++, p++)
;
tmp2 = NEW_PLIST(T_PLIST_DENSE, len);
SET_LEN_PLIST(tmp2, len);
for (i = 1, p = he->h_aliases; i <= len; i++, p++) {
tmp = MakeString(*p);
SET_ELM_PLIST(tmp2, i, tmp);
CHANGED_BAG(tmp2);
}
AssPRec(res, RNamName("aliases" ), tmp2);
AssPRec(res, RNamName("addrtype" ), INTOBJ_INT(he->h_addrtype));
AssPRec(res, RNamName("length" ), INTOBJ_INT(he->h_length));
for (len = 0, p = he->h_addr_list; *p != NULL; len++, p++)
;
tmp2 = NEW_PLIST(T_PLIST_DENSE, len);
SET_LEN_PLIST(tmp2, len);
for (i = 1, p = he->h_addr_list; i <= len; i++, p++) {
tmp = MakeStringWithLen(*p, he->h_length);
SET_ELM_PLIST(tmp2, i, tmp);
CHANGED_BAG(tmp2);
}
AssPRec(res, RNamName("addr" ), tmp2);
return res;
}
#endif
#ifdef HAVE_LISTEN
static Obj FuncIO_listen(Obj self, Obj s, Obj backlog)
{
int res;
if (!IS_INTOBJ(s) || !IS_INTOBJ(backlog)) {
SyClearErrorNo();
return Fail;
}
res = listen(INT_INTOBJ(s), INT_INTOBJ(backlog));
if (res < 0) {
SySetErrorNo();
return Fail;
}
return True ;
}
#endif
#ifdef HAVE_ACCEPT
static Obj FuncIO_accept(Obj self, Obj fd, Obj addr)
{
int res;
socklen_t len;
if (!IS_INTOBJ(fd) || !IS_STRING(addr) || !IS_STRING_REP(addr)) {
SyClearErrorNo();
return Fail;
}
len = GET_LEN_STRING(addr);
res =
accept(INT_INTOBJ(fd), (struct sockaddr *)(CHARS_STRING(addr)), &len);
if (res < 0) {
SySetErrorNo();
return Fail;
}
return INTOBJ_INT(res);
}
#endif
#ifdef HAVE_RECV
static Obj
FuncIO_recv(Obj self, Obj fd, Obj st, Obj offset, Obj count, Obj flags)
{
Int bytes;
Int len;
if (!IS_INTOBJ(fd) || !IS_STRING(st) || !IS_STRING_REP(st) ||
!IS_INTOBJ(count) || !IS_INTOBJ(flags)) {
SyClearErrorNo();
return Fail;
}
len = INT_INTOBJ(offset) + INT_INTOBJ(count);
if (len > GET_LEN_STRING(st))
GrowString(st, len);
bytes = recv(INT_INTOBJ(fd), CHARS_STRING(st) + INT_INTOBJ(offset),
INT_INTOBJ(count), INT_INTOBJ(flags));
if (bytes < 0) {
SySetErrorNo();
return Fail;
}
if (bytes + INT_INTOBJ(offset) > GET_LEN_STRING(st)) {
SET_LEN_STRING(st, bytes + INT_INTOBJ(offset));
CHARS_STRING(st)[len] = 0;
}
return INTOBJ_INT(bytes);
}
#endif
#ifdef HAVE_RECVFROM
static Obj FuncIO_recvfrom(
Obj self, Obj fd, Obj st, Obj offset, Obj count, Obj flags, Obj from)
{
Int bytes;
Int len;
socklen_t fromlen;
if (!IS_INTOBJ(fd) || !IS_STRING(st) || !IS_STRING_REP(st) ||
!IS_INTOBJ(count) || !IS_INTOBJ(flags) || !IS_STRING(from) ||
!IS_STRING_REP(from)) {
SyClearErrorNo();
return Fail;
}
len = INT_INTOBJ(offset) + INT_INTOBJ(count);
if (len > GET_LEN_STRING(st))
GrowString(st, len);
fromlen = GET_LEN_STRING(from);
bytes = recvfrom(INT_INTOBJ(fd), CSTR_STRING(st) + INT_INTOBJ(offset),
INT_INTOBJ(count), INT_INTOBJ(flags),
(struct sockaddr *)CHARS_STRING(from), &fromlen);
if (bytes < 0) {
SySetErrorNo();
return Fail;
}
if (bytes + INT_INTOBJ(offset) > GET_LEN_STRING(st)) {
SET_LEN_STRING(st, bytes + INT_INTOBJ(offset));
CHARS_STRING(st)[len] = 0;
}
return INTOBJ_INT(bytes);
}
#endif
#ifdef HAVE_SEND
static Obj
FuncIO_send(Obj self, Obj fd, Obj st, Obj offset, Obj count, Obj flags)
{
Int bytes;
if (!IS_INTOBJ(fd) || !IS_STRING(st) || !IS_STRING_REP(st) ||
!IS_INTOBJ(offset) || !IS_INTOBJ(count) || !IS_INTOBJ(flags)) {
SyClearErrorNo();
return Fail;
}
if (GET_LEN_STRING(st) < INT_INTOBJ(offset) + INT_INTOBJ(count)) {
SyClearErrorNo();
return Fail;
}
bytes = (Int )send(INT_INTOBJ(fd), CSTR_STRING(st) + INT_INTOBJ(offset),
INT_INTOBJ(count), INT_INTOBJ(flags));
if (bytes < 0) {
SySetErrorNo();
return Fail;
}
return INTOBJ_INT(bytes);
}
#endif
#ifdef HAVE_SENDTO
static Obj FuncIO_sendto(
Obj self, Obj fd, Obj st, Obj offset, Obj count, Obj flags, Obj to)
{
Int bytes;
socklen_t fromlen;
if (!IS_INTOBJ(fd) || !IS_STRING(st) || !IS_STRING_REP(st) ||
!IS_INTOBJ(offset) || !IS_INTOBJ(count) || !IS_INTOBJ(flags) ||
!IS_STRING(to) || !IS_STRING_REP(to)) {
SyClearErrorNo();
return Fail;
}
if (GET_LEN_STRING(st) < INT_INTOBJ(offset) + INT_INTOBJ(count)) {
SyClearErrorNo();
return Fail;
}
fromlen = GET_LEN_STRING(to);
bytes = (Int )sendto(INT_INTOBJ(fd), CSTR_STRING(st) + INT_INTOBJ(offset),
INT_INTOBJ(count), INT_INTOBJ(flags),
(struct sockaddr *)CHARS_STRING(to), fromlen);
if (bytes < 0) {
SySetErrorNo();
return Fail;
}
return INTOBJ_INT(bytes);
}
#endif
#ifdef HAVE_GETSOCKOPT
static Obj FuncIO_getsockopt(
Obj self, Obj fd, Obj level, Obj optname, Obj optval, Obj optlen)
{
int res;
socklen_t olen;
if (!IS_INTOBJ(fd) || !IS_INTOBJ(level) || !IS_INTOBJ(optname) ||
!IS_INTOBJ(optlen) || !IS_STRING(optval) || !IS_STRING_REP(optval)) {
SyClearErrorNo();
return Fail;
}
olen = INT_INTOBJ(optlen);
if (olen > GET_LEN_STRING(optval))
GrowString(optval, olen);
res = (Int )getsockopt(INT_INTOBJ(fd), INT_INTOBJ(level),
INT_INTOBJ(optname), CSTR_STRING(optval), &olen);
if (res < 0) {
SySetErrorNo();
return Fail;
}
SET_LEN_STRING(optval, olen);
return True ;
}
#endif
#ifdef HAVE_SETSOCKOPT
static Obj
FuncIO_setsockopt(Obj self, Obj fd, Obj level, Obj optname, Obj optval)
{
int res;
socklen_t olen;
if (!IS_INTOBJ(fd) || !IS_INTOBJ(level) || !IS_INTOBJ(optname) ||
!IS_STRING(optval) || !IS_STRING_REP(optval)) {
SyClearErrorNo();
return Fail;
}
olen = GET_LEN_STRING(optval);
res = (Int )setsockopt(INT_INTOBJ(fd), INT_INTOBJ(level),
INT_INTOBJ(optname), CSTR_STRING(optval), olen);
if (res < 0) {
SySetErrorNo();
return Fail;
}
return True ;
}
#endif
#ifdef HAVE_SELECT
static Obj FuncIO_select(Obj self,
Obj inlist,
Obj outlist,
Obj exclist,
Obj timeoutsec,
Obj timeoutusec)
{
fd_set infds, outfds, excfds;
struct timeval tv;
int n, maxfd;
Int i, j;
Obj o;
time_t t1, t2;
if (!IS_PLIST(inlist))
ErrorMayQuit(" must be a list of small integers (not a %s)" ,
(Int )TNAM_OBJ(inlist), 0);
if (!IS_PLIST(outlist))
ErrorMayQuit(" must be a list of small integers (not a %s)" ,
(Int )TNAM_OBJ(outlist), 0);
if (!IS_PLIST(exclist))
ErrorMayQuit(" must be a list of small integers (not a %s)" ,
(Int )TNAM_OBJ(exclist), 0);
FD_ZERO(&infds);
FD_ZERO(&outfds);
FD_ZERO(&excfds);
maxfd = 0;
// Handle input file descriptors:
for (i = 1; i <= LEN_PLIST(inlist); i++) {
o = ELM_PLIST(inlist, i);
if (o != (Obj)0 && IS_INTOBJ(o)) {
j = INT_INTOBJ(o); // a UNIX file descriptor
FD_SET(j, &infds);
if (j > maxfd)
maxfd = j;
}
}
// Handle output file descriptors:
for (i = 1; i <= LEN_PLIST(outlist); i++) {
o = ELM_PLIST(outlist, i);
if (o != (Obj)0 && IS_INTOBJ(o)) {
j = INT_INTOBJ(o); // a UNIX file descriptor
FD_SET(j, &outfds);
if (j > maxfd)
maxfd = j;
}
}
// Handle exception file descriptors:
for (i = 1; i <= LEN_PLIST(exclist); i++) {
o = ELM_PLIST(exclist, i);
if (o != (Obj)0 && IS_INTOBJ(o)) {
j = INT_INTOBJ(o); // a UNIX file descriptor
FD_SET(j, &excfds);
if (j > maxfd)
maxfd = j;
}
}
// Handle the timeout:
if (timeoutsec != (Obj)0 && IS_INTOBJ(timeoutsec) &&
timeoutusec != (Obj)0 && IS_INTOBJ(timeoutusec)) {
tv.tv_sec = INT_INTOBJ(timeoutsec);
tv.tv_usec = INT_INTOBJ(timeoutusec);
while (1) {
t1 = time(NULL);
n = select(maxfd + 1, &infds, &outfds, &excfds, &tv);
if (n != -1 || errno != EINTR)
break ;
t2 = time(NULL);
tv.tv_sec -= (t2 - t1);
if (tv.tv_sec < 0) {
tv.tv_sec = 0;
tv.tv_usec = 0;
}
}
}
else {
do {
n = select(maxfd + 1, &infds, &outfds, &excfds, NULL);
} while (n == -1 && errno == EINTR);
}
if (n >= 0) {
// Now run through the lists and call functions if ready:
for (i = 1; i <= LEN_PLIST(inlist); i++) {
o = ELM_PLIST(inlist, i);
if (o != (Obj)0 && IS_INTOBJ(o)) {
j = INT_INTOBJ(o); // a UNIX file descriptor
if (!(FD_ISSET(j, &infds))) {
SET_ELM_PLIST(inlist, i, Fail);
CHANGED_BAG(inlist);
}
}
}
// Handle output file descriptors:
for (i = 1; i <= LEN_PLIST(outlist); i++) {
o = ELM_PLIST(outlist, i);
if (o != (Obj)0 && IS_INTOBJ(o)) {
j = INT_INTOBJ(o); // a UNIX file descriptor
if (!(FD_ISSET(j, &outfds))) {
SET_ELM_PLIST(outlist, i, Fail);
CHANGED_BAG(outlist);
}
}
}
// Handle exception file descriptors:
for (i = 1; i <= LEN_PLIST(exclist); i++) {
o = ELM_PLIST(exclist, i);
if (o != (Obj)0 && IS_INTOBJ(o)) {
j = INT_INTOBJ(o); // a UNIX file descriptor
if (!(FD_ISSET(j, &excfds))) {
SET_ELM_PLIST(exclist, i, Fail);
CHANGED_BAG(exclist);
}
}
}
return INTOBJ_INT(n);
}
else {
SySetErrorNo();
return Fail;
}
}
#endif
#ifdef HAVE_FORK
static Obj FuncIO_fork(Obj self)
{
int res;
FuncIO_InstallSIGCHLDHandler(0);
// Ensure files are flushed before forking
fflush(0);
res = fork();
if (res == -1) {
SySetErrorNo();
return Fail;
}
#if GAP_KERNEL_MAJOR_VERSION >= 6
if (res == 0) {
// In child
InformProfilingThatThisIsAForkedGAP();
}
#endif
return INTOBJ_INT(res);
}
#endif
static Obj FuncIO_execv(Obj self, Obj path, Obj Argv)
{
int argc;
char * argv[1024]; // Up to 1024 arguments
int i;
Obj tmp;
if (!IS_STRING(path) || !IS_STRING_REP(path) || !IS_PLIST(Argv)) {
SyClearErrorNo();
return Fail;
}
argv[0] = CSTR_STRING(path);
argc = LEN_PLIST(Argv);
if (argc > 1022) {
Pr("#E Ignored arguments after the 1022th.\n" , 0, 0);
argc = 1022;
}
for (i = 1; i <= argc; i++) {
tmp = ELM_PLIST(Argv, i);
if (!IS_STRING(tmp) || !IS_STRING_REP(tmp)) {
SyClearErrorNo();
return Fail;
}
argv[i] = CSTR_STRING(tmp);
}
argv[i] = 0;
i = execv(CSTR_STRING(path), argv);
if (i == -1) {
SySetErrorNo();
return INTOBJ_INT(i);
}
// This will never happen:
return Fail;
}
static Obj FuncIO_execvp(Obj self, Obj file, Obj Argv)
{
int argc;
char * argv[1024]; // Up to 1024 arguments
int i;
Obj tmp;
if (!IS_STRING(file) || !IS_STRING_REP(file) || !IS_PLIST(Argv)) {
SyClearErrorNo();
return Fail;
}
argv[0] = CSTR_STRING(file);
argc = LEN_PLIST(Argv);
if (argc > 1022) {
Pr("#E Ignored arguments after the 1022th.\n" , 0, 0);
argc = 1022;
}
for (i = 1; i <= argc; i++) {
tmp = ELM_PLIST(Argv, i);
if (!IS_STRING(tmp) || !IS_STRING_REP(tmp)) {
SyClearErrorNo();
return Fail;
}
argv[i] = CSTR_STRING(tmp);
}
argv[i] = 0;
i = execvp(CSTR_STRING(file), argv);
if (i == -1) {
SySetErrorNo();
return Fail;
}
// This will never happen:
return Fail;
}
static Obj FuncIO_execve(Obj self, Obj path, Obj Argv, Obj Envp)
{
int argc;
char * argv[1024]; // Up to 1024 arguments
char * envp[1024]; // Up to 1024 environment entries
int i;
Obj tmp;
if (!IS_STRING(path) || !IS_STRING_REP(path) || !IS_PLIST(Argv) ||
!IS_PLIST(Envp)) {
SyClearErrorNo();
return Fail;
}
argv[0] = CSTR_STRING(path);
argc = LEN_PLIST(Argv);
if (argc > 1022) {
Pr("#E Ignored arguments after the 1022th.\n" , 0, 0);
argc = 1022;
}
for (i = 1; i <= argc; i++) {
tmp = ELM_PLIST(Argv, i);
if (!IS_STRING(tmp) || !IS_STRING_REP(tmp)) {
SyClearErrorNo();
return Fail;
}
argv[i] = CSTR_STRING(tmp);
}
argv[i] = 0;
argc = LEN_PLIST(Envp);
if (argc > 1022) {
Pr("#E Ignored environment strings after the 1022th.\n" , 0, 0);
argc = 1022;
}
for (i = 1; i <= argc; i++) {
tmp = ELM_PLIST(Envp, i);
if (!IS_STRING(tmp) || !IS_STRING_REP(tmp)) {
SyClearErrorNo();
return Fail;
}
envp[i - 1] = CSTR_STRING(tmp);
}
envp[i - 1] = 0;
i = execve(CSTR_STRING(path), argv, envp);
if (i == -1) {
SySetErrorNo();
return Fail;
}
// This will never happen:
return Fail;
}
extern char ** environ;
static Obj FuncIO_environ(Obj self)
{
Int i, len;
char ** p;
Obj tmp, tmp2;
// First count the entries:
for (len = 0, p = environ; *p; p++, len++)
;
// Now make a list:
tmp = NEW_PLIST(T_PLIST_DENSE, len);
tmp2 = tmp; // Just to please the compiler
SET_LEN_PLIST(tmp2, len);
for (i = 1, p = environ; i <= len; i++, p++) {
tmp2 = MakeString(*p);
SET_ELM_PLIST(tmp, i, tmp2);
CHANGED_BAG(tmp);
}
return tmp;
}
static Obj FuncIO_pipe(Obj self)
{
Obj tmp;
int fds[2];
int res;
res = pipe(fds);
if (res == -1) {
SySetErrorNo();
return Fail;
}
tmp = NEW_PREC(0);
AssPRec(tmp, RNamName("toread" ), INTOBJ_INT(fds[0]));
AssPRec(tmp, RNamName("towrite" ), INTOBJ_INT(fds[1]));
return tmp;
}
static Obj FuncIO_exit(Obj self, Obj status)
{
if (!IS_INTOBJ(status)) {
SyClearErrorNo();
return Fail;
}
exit (INT_INTOBJ(status));
// This never happens:
return True ;
}
#ifdef HAVE_FCNTL_H
static Obj FuncIO_fcntl(Obj self, Obj fd, Obj cmd, Obj arg)
{
int res;
if (!IS_INTOBJ(fd) || !IS_INTOBJ(cmd) || !IS_INTOBJ(arg)) {
SyClearErrorNo();
return Fail;
}
res = fcntl(INT_INTOBJ(fd), INT_INTOBJ(cmd), INT_INTOBJ(arg));
if (res == -1) {
SySetErrorNo();
return Fail;
}
return INTOBJ_INT(res);
}
#endif
#ifdef HAVE_GETPID
static Obj FuncIO_getpid(Obj self)
{
return INTOBJ_INT(getpid());
}
#endif
#ifdef HAVE_GETPPID
static Obj FuncIO_getppid(Obj self)
{
return INTOBJ_INT(getppid());
}
#endif
#ifdef HAVE_KILL
static Obj FuncIO_kill(Obj self, Obj pid, Obj sig)
{
int res;
if (!IS_INTOBJ(pid) || !IS_INTOBJ(sig)) {
SyClearErrorNo();
return Fail;
}
res = kill((pid_t)INT_INTOBJ(pid), (int )INT_INTOBJ(sig));
if (res == -1) {
SySetErrorNo();
return Fail;
}
return True ;
}
#endif
#ifdef HAVE_GETTIMEOFDAY
static Obj FuncIO_gettimeofday(Obj self)
{
Obj tmp;
struct timeval tv;
gettimeofday(&tv, NULL);
tmp = NEW_PREC(0);
AssPRec(tmp, RNamName("tv_sec" ), ObjInt_Int(tv.tv_sec));
AssPRec(tmp, RNamName("tv_usec" ), ObjInt_Int(tv.tv_usec));
return tmp;
}
#endif
#ifdef HAVE_GMTIME
static Obj FuncIO_gmtime(Obj self, Obj time)
{
Obj tmp;
time_t t;
struct tm * s;
if (!IS_INT(time)) {
SyClearErrorNo();
return Fail;
}
if (!IS_INTOBJ(time)) {
tmp = QuoInt(time, INTOBJ_INT(256));
if (!IS_INTOBJ(tmp))
return Fail;
t = INT_INTOBJ(tmp) * 256 + INT_INTOBJ(ModInt(time, INTOBJ_INT(256)));
}
else
t = INT_INTOBJ(time);
s = gmtime(&t);
if (s == NULL)
return Fail;
tmp = NEW_PREC(0);
AssPRec(tmp, RNamName("tm_sec" ), INTOBJ_INT(s->tm_sec));
AssPRec(tmp, RNamName("tm_min" ), INTOBJ_INT(s->tm_min));
AssPRec(tmp, RNamName("tm_hour" ), INTOBJ_INT(s->tm_hour));
AssPRec(tmp, RNamName("tm_mday" ), INTOBJ_INT(s->tm_mday));
AssPRec(tmp, RNamName("tm_mon" ), INTOBJ_INT(s->tm_mon));
AssPRec(tmp, RNamName("tm_year" ), INTOBJ_INT(s->tm_year));
AssPRec(tmp, RNamName("tm_wday" ), INTOBJ_INT(s->tm_wday));
AssPRec(tmp, RNamName("tm_yday" ), INTOBJ_INT(s->tm_yday));
AssPRec(tmp, RNamName("tm_isdst" ), INTOBJ_INT(s->tm_isdst));
return tmp;
}
#endif
#ifdef HAVE_LOCALTIME
static Obj FuncIO_localtime(Obj self, Obj time)
{
Obj tmp;
time_t t;
struct tm * s;
if (!IS_INT(time)) {
SyClearErrorNo();
return Fail;
}
if (!IS_INTOBJ(time)) {
tmp = QuoInt(time, INTOBJ_INT(256));
if (!IS_INTOBJ(tmp))
return Fail;
t = INT_INTOBJ(tmp) * 256 + INT_INTOBJ(ModInt(time, INTOBJ_INT(256)));
}
else
t = INT_INTOBJ(time);
s = localtime(&t);
if (s == NULL)
return Fail;
tmp = NEW_PREC(0);
AssPRec(tmp, RNamName("tm_sec" ), INTOBJ_INT(s->tm_sec));
AssPRec(tmp, RNamName("tm_min" ), INTOBJ_INT(s->tm_min));
AssPRec(tmp, RNamName("tm_hour" ), INTOBJ_INT(s->tm_hour));
AssPRec(tmp, RNamName("tm_mday" ), INTOBJ_INT(s->tm_mday));
AssPRec(tmp, RNamName("tm_mon" ), INTOBJ_INT(s->tm_mon));
AssPRec(tmp, RNamName("tm_year" ), INTOBJ_INT(s->tm_year));
AssPRec(tmp, RNamName("tm_wday" ), INTOBJ_INT(s->tm_wday));
AssPRec(tmp, RNamName("tm_yday" ), INTOBJ_INT(s->tm_yday));
AssPRec(tmp, RNamName("tm_isdst" ), INTOBJ_INT(s->tm_isdst));
return tmp;
}
#endif
#ifdef HAVE_GETSOCKNAME
static Obj FuncIO_getsockname(Obj self, Obj fd)
{
struct sockaddr_in sa;
socklen_t sa_len;
if (!IS_INTOBJ(fd)) {
SyClearErrorNo();
return Fail;
}
sa_len = sizeof sa;
getsockname(INT_INTOBJ(fd), (struct sockaddr *)(&sa), &sa_len);
return MakeStringWithLen((void *)&sa, sa_len);
}
#endif
#ifdef HAVE_GETHOSTNAME
static Obj FuncIO_gethostname(Obj self)
{
char name[256];
int r;
r = gethostname(name, 256);
if (r < 0) {
return Fail;
}
return MakeString(name);
}
#endif
static Obj FuncIO_getenv(Obj self, Obj name)
{
if (!IS_STRING_REP(name)) {
SyClearErrorNo();
return Fail;
}
char * res = getenv(CONST_CSTR_STRING(name));
if (res == NULL) {
SySetErrorNo();
return Fail;
}
return MakeString(res);
}
static Obj FuncIO_setenv(Obj self, Obj name, Obj value, Obj overwrite)
{
if (!IS_STRING_REP(name) || !IS_STRING_REP(value) ||
(overwrite != True && overwrite != False )) {
SyClearErrorNo();
return Fail;
}
int res = setenv(CONST_CSTR_STRING(name), CONST_CSTR_STRING(value),
overwrite == True );
if (res < 0) {
SySetErrorNo();
return Fail;
}
return True ;
}
static Obj FuncIO_unsetenv(Obj self, Obj name)
{
if (!IS_STRING_REP(name)) {
SyClearErrorNo();
return Fail;
}
int res = unsetenv(CONST_CSTR_STRING(name));
if (res < 0) {
SySetErrorNo();
return Fail;
}
return True ;
}
//
// list of functions to export
//
static StructGVarFunc GVarFuncs[] = {
GVAR_FUNC(IO_open, 3, "pathname, flags, mode" ),
GVAR_FUNC(IO_creat, 2, "pathname, mode" ),
GVAR_FUNC(IO_read, 4, "fd, st, offset, count" ),
GVAR_FUNC(IO_write, 4, "fd, st, offset, count" ),
GVAR_FUNC(IO_close, 1, "fd" ),
GVAR_FUNC(IO_lseek, 3, "fd, offset, whence" ),
#ifdef HAVE_DIRENT_H
#ifdef HAVE_OPENDIR
GVAR_FUNC(IO_opendir, 1, "name" ),
#endif
#ifdef HAVE_READDIR
GVAR_FUNC(IO_readdir, 0, "" ),
#endif
#ifdef HAVE_REWINDDIR
GVAR_FUNC(IO_rewinddir, 0, "" ),
#endif
#ifdef HAVE_CLOSEDIR
GVAR_FUNC(IO_closedir, 0, "" ),
#endif
#ifdef HAVE_TELLDIR
GVAR_FUNC(IO_telldir, 0, "" ),
#endif
#ifdef HAVE_SEEKDIR
GVAR_FUNC(IO_seekdir, 1, "offset" ),
#endif
#endif // HAVE_DIRENT_H
#ifdef HAVE_UNLINK
GVAR_FUNC(IO_unlink, 1, "pathname" ),
#endif
#ifdef HAVE_LINK
GVAR_FUNC(IO_link, 2, "oldpath, newpath" ),
#endif
#ifdef HAVE_RENAME
GVAR_FUNC(IO_rename, 2, "oldpath, newpath" ),
#endif
#ifdef HAVE_SYMLINK
GVAR_FUNC(IO_symlink, 2, "oldpath, newpath" ),
#endif
#ifdef HAVE_READLINK
GVAR_FUNC(IO_readlink, 3, "path, buf, bufsize" ),
#endif
GVAR_FUNC(IO_realpath, 1, "path" ),
#ifdef HAVE_MKDIR
GVAR_FUNC(IO_mkdir, 2, "pathname, mode" ),
#endif
GVAR_FUNC(IO_chdir, 1, "path" ),
GVAR_FUNC(IO_getcwd, 0, "" ),
#ifdef HAVE_RMDIR
GVAR_FUNC(IO_rmdir, 1, "pathname" ),
#endif
#ifdef HAVE_STAT
GVAR_FUNC(IO_stat, 1, "pathname" ),
#endif
#ifdef HAVE_FSTAT
GVAR_FUNC(IO_fstat, 1, "fd" ),
#endif
#ifdef HAVE_LSTAT
GVAR_FUNC(IO_lstat, 1, "pathname" ),
#endif
#ifdef HAVE_CHMOD
GVAR_FUNC(IO_chmod, 2, "path, mode" ),
#endif
#ifdef HAVE_FCHMOD
GVAR_FUNC(IO_fchmod, 2, "fd, mode" ),
#endif
#ifdef HAVE_CHOWN
GVAR_FUNC(IO_chown, 3, "path, owner, group" ),
#endif
#ifdef HAVE_FCHOWN
GVAR_FUNC(IO_fchown, 3, "fd, owner, group" ),
#endif
#ifdef HAVE_LCHOWN
GVAR_FUNC(IO_lchown, 3, "path, owner, group" ),
#endif
#ifdef HAVE_MKNOD
GVAR_FUNC(IO_mknod, 3, "path, mode, dev" ),
#endif
#ifdef HAVE_MKSTEMP
GVAR_FUNC(IO_mkstemp, 1, "template" ),
#endif
#ifdef HAVE_MKDTEMP
GVAR_FUNC(IO_mkdtemp, 1, "template" ),
#endif
#ifdef HAVE_MKFIFO
GVAR_FUNC(IO_mkfifo, 2, "path, mode" ),
#endif
#ifdef HAVE_DUP
GVAR_FUNC(IO_dup, 1, "oldfd" ),
#endif
#ifdef HAVE_DUP2
GVAR_FUNC(IO_dup2, 2, "oldfd, newfd" ),
#endif
#ifdef HAVE_SOCKET
GVAR_FUNC(IO_socket, 3, "domain, type, protocol" ),
#endif
#ifdef HAVE_BIND
GVAR_FUNC(IO_bind, 2, "fd, my_addr" ),
#endif
#ifdef HAVE_CONNECT
GVAR_FUNC(IO_connect, 2, "fd, serv_addr" ),
#endif
#ifdef HAVE_SOCKET
GVAR_FUNC(IO_make_sockaddr_in, 2, "ip, port" ),
#endif
#ifdef HAVE_GETHOSTBYNAME
GVAR_FUNC(IO_gethostbyname, 1, "name" ),
#endif
#ifdef HAVE_LISTEN
GVAR_FUNC(IO_listen, 2, "s, backlog" ),
#endif
#ifdef HAVE_ACCEPT
GVAR_FUNC(IO_accept, 2, "fd, addr" ),
#endif
#ifdef HAVE_RECV
GVAR_FUNC(IO_recv, 5, "fd, st, offset, len, flags" ),
#endif
#ifdef HAVE_RECVFROM
GVAR_FUNC(IO_recvfrom, 6, "fd, st, offset, len, flags, from" ),
#endif
#ifdef HAVE_SEND
GVAR_FUNC(IO_send, 5, "fd, st, offset, len, flags" ),
#endif
#ifdef HAVE_SENDTO
GVAR_FUNC(IO_sendto, 6, "fd, st, offset, len, flags, to" ),
#endif
#ifdef HAVE_GETSOCKOPT
GVAR_FUNC(IO_getsockopt, 5, "fd, level, optname, optval, optlen" ),
#endif
#ifdef HAVE_SETSOCKOPT
GVAR_FUNC(IO_setsockopt, 4, "fd, level, optname, optval" ),
#endif
#ifdef HAVE_SELECT
GVAR_FUNC(
IO_select, 5, "inlist, outlist, exclist, timeoutsec, timeoutusec" ),
#endif
GVAR_FUNC(IO_IgnorePid, 1, "pid" ),
#if defined (HAVE_SIGACTION) || defined (HAVE_SIGNAL)
GVAR_FUNC(IO_WaitPid, 2, "pid, wait" ),
#endif
#ifdef HAVE_FORK
GVAR_FUNC(IO_fork, 0, "" ),
#endif
GVAR_FUNC(IO_execv, 2, "path, argv" ),
GVAR_FUNC(IO_execvp, 2, "path, argv" ),
GVAR_FUNC(IO_execve, 3, "path, argv, envp" ),
GVAR_FUNC(IO_environ, 0, "" ),
#ifdef HAVE_SIGNAL
GVAR_FUNC(IO_InstallSIGCHLDHandler, 0, "" ),
GVAR_FUNC(IO_RestoreSIGCHLDHandler, 0, "" ),
#endif
GVAR_FUNC(IO_pipe, 0, "" ),
GVAR_FUNC(IO_exit, 1, "status" ),
#ifdef HAVE_FCNTL_H
GVAR_FUNC(IO_fcntl, 3, "fd, cmd, arg" ),
#endif
#ifdef HAVE_GETPID
GVAR_FUNC(IO_getpid, 0, "" ),
#endif
#ifdef HAVE_GETPPID
GVAR_FUNC(IO_getppid, 0, "" ),
#endif
#ifdef HAVE_KILL
GVAR_FUNC(IO_kill, 2, "pid, sig" ),
#endif
#ifdef HAVE_GETTIMEOFDAY
GVAR_FUNC(IO_gettimeofday, 0, "" ),
#endif
#ifdef HAVE_GMTIME
GVAR_FUNC(IO_gmtime, 1, "seconds" ),
#endif
#ifdef HAVE_LOCALTIME
GVAR_FUNC(IO_localtime, 1, "seconds" ),
#endif
#ifdef HAVE_GETSOCKNAME
GVAR_FUNC(IO_getsockname, 1, "fd" ),
#endif
#ifdef HAVE_GETHOSTNAME
GVAR_FUNC(IO_gethostname, 0, "" ),
#endif
GVAR_FUNC(IO_getenv, 1, "name" ),
GVAR_FUNC(IO_setenv, 3, "name, value, overwrite" ),
GVAR_FUNC(IO_unsetenv, 1, "name" ),
{ 0 }
};
// initialise kernel data structures
static Int InitKernel(StructInitInfo * module)
{
// init filters and functions
InitHdlrFuncsFromTable(GVarFuncs);
// return success
return 0;
}
// initialise library data structures
static Int InitLibrary(StructInitInfo * module)
{
Int gvar;
Obj tmp;
// init filters and functions we assign the functions to components of a
// record "IO"
InitGVarFuncsFromTable(GVarFuncs);
tmp = NEW_PREC(0);
// Constants for the flags:
AssPRec(tmp, RNamName("O_RDONLY" ), INTOBJ_INT((Int )O_RDONLY));
AssPRec(tmp, RNamName("O_WRONLY" ), INTOBJ_INT((Int )O_WRONLY));
AssPRec(tmp, RNamName("O_RDWR" ), INTOBJ_INT((Int )O_RDWR));
#ifdef O_CREAT
AssPRec(tmp, RNamName("O_CREAT" ), INTOBJ_INT((Int )O_CREAT));
#endif
#ifdef O_APPEND
AssPRec(tmp, RNamName("O_APPEND" ), INTOBJ_INT((Int )O_APPEND));
#endif
#ifdef O_ASYNC
AssPRec(tmp, RNamName("O_ASYNC" ), INTOBJ_INT((Int )O_ASYNC));
#endif
#ifdef O_DIRECT
AssPRec(tmp, RNamName("O_DIRECT" ), INTOBJ_INT((Int )O_DIRECT));
#endif
#ifdef O_DIRECTORY
AssPRec(tmp, RNamName("O_DIRECTORY" ), INTOBJ_INT((Int )O_DIRECTORY));
#endif
#ifdef O_EXCL
AssPRec(tmp, RNamName("O_EXCL" ), INTOBJ_INT((Int )O_EXCL));
#endif
#ifdef O_LARGEFILE
AssPRec(tmp, RNamName("O_LARGEFILE" ), INTOBJ_INT((Int )O_LARGEFILE));
#endif
#ifdef O_NOATIME
AssPRec(tmp, RNamName("O_NOATIME" ), INTOBJ_INT((Int )O_NOATIME));
#endif
#ifdef O_NOCTTY
AssPRec(tmp, RNamName("O_NOCTTY" ), INTOBJ_INT((Int )O_NOCTTY));
#endif
#ifdef O_NOFOLLOW
AssPRec(tmp, RNamName("O_NOFOLLOW" ), INTOBJ_INT((Int )O_NOFOLLOW));
#endif
#ifdef O_NONBLOCK
AssPRec(tmp, RNamName("O_NONBLOCK" ), INTOBJ_INT((Int )O_NONBLOCK));
#endif
#ifdef O_NDELAY
AssPRec(tmp, RNamName("O_NDELAY" ), INTOBJ_INT((Int )O_NDELAY));
#endif
#ifdef O_SYNC
AssPRec(tmp, RNamName("O_SYNC" ), INTOBJ_INT((Int )O_SYNC));
#endif
#ifdef O_TRUNC
AssPRec(tmp, RNamName("O_TRUNC" ), INTOBJ_INT((Int )O_TRUNC));
#endif
#ifdef SEEK_SET
AssPRec(tmp, RNamName("SEEK_SET" ), INTOBJ_INT((Int )SEEK_SET));
#endif
#ifdef SEEK_CUR
AssPRec(tmp, RNamName("SEEK_CUR" ), INTOBJ_INT((Int )SEEK_CUR));
#endif
#ifdef SEEK_END
AssPRec(tmp, RNamName("SEEK_END" ), INTOBJ_INT((Int )SEEK_END));
#endif
// Constants for the mode:
#ifdef S_IRWXU
AssPRec(tmp, RNamName("S_IRWXU" ), INTOBJ_INT((Int )S_IRWXU));
#endif
#ifdef S_IRUSR
AssPRec(tmp, RNamName("S_IRUSR" ), INTOBJ_INT((Int )S_IRUSR));
#endif
#ifdef S_IWUSR
AssPRec(tmp, RNamName("S_IWUSR" ), INTOBJ_INT((Int )S_IWUSR));
#endif
#ifdef S_IXUSR
AssPRec(tmp, RNamName("S_IXUSR" ), INTOBJ_INT((Int )S_IXUSR));
#endif
#ifdef S_IRWXG
AssPRec(tmp, RNamName("S_IRWXG" ), INTOBJ_INT((Int )S_IRWXG));
#endif
#ifdef S_IRGRP
AssPRec(tmp, RNamName("S_IRGRP" ), INTOBJ_INT((Int )S_IRGRP));
#endif
#ifdef S_IWGRP
AssPRec(tmp, RNamName("S_IWGRP" ), INTOBJ_INT((Int )S_IWGRP));
#endif
#ifdef S_IXGRP
AssPRec(tmp, RNamName("S_IXGRP" ), INTOBJ_INT((Int )S_IXGRP));
#endif
#ifdef S_IRWXO
AssPRec(tmp, RNamName("S_IRWXO" ), INTOBJ_INT((Int )S_IRWXO));
#endif
#ifdef S_IROTH
AssPRec(tmp, RNamName("S_IROTH" ), INTOBJ_INT((Int )S_IROTH));
#endif
#ifdef S_IWOTH
AssPRec(tmp, RNamName("S_IWOTH" ), INTOBJ_INT((Int )S_IWOTH));
#endif
#ifdef S_IXOTH
AssPRec(tmp, RNamName("S_IXOTH" ), INTOBJ_INT((Int )S_IXOTH));
#endif
#ifdef S_IFMT
AssPRec(tmp, RNamName("S_IFMT" ), INTOBJ_INT((Int )S_IFMT));
#endif
#ifdef S_IFSOCK
AssPRec(tmp, RNamName("S_IFSOCK" ), INTOBJ_INT((Int )S_IFSOCK));
#endif
#ifdef S_IFLNK
AssPRec(tmp, RNamName("S_IFLNK" ), INTOBJ_INT((Int )S_IFLNK));
#endif
#ifdef S_IFREG
AssPRec(tmp, RNamName("S_IFREG" ), INTOBJ_INT((Int )S_IFREG));
#endif
#ifdef S_IFBLK
AssPRec(tmp, RNamName("S_IFBLK" ), INTOBJ_INT((Int )S_IFBLK));
#endif
#ifdef S_IFDIR
AssPRec(tmp, RNamName("S_IFDIR" ), INTOBJ_INT((Int )S_IFDIR));
#endif
#ifdef S_IFCHR
AssPRec(tmp, RNamName("S_IFCHR" ), INTOBJ_INT((Int )S_IFCHR));
#endif
#ifdef S_IFIFO
AssPRec(tmp, RNamName("S_IFIFO" ), INTOBJ_INT((Int )S_IFIFO));
#endif
#ifdef S_ISUID
AssPRec(tmp, RNamName("S_ISUID" ), INTOBJ_INT((Int )S_ISUID));
#endif
#ifdef S_ISGID
AssPRec(tmp, RNamName("S_ISGID" ), INTOBJ_INT((Int )S_ISGID));
#endif
#ifdef S_ISVTX
AssPRec(tmp, RNamName("S_ISVTX" ), INTOBJ_INT((Int )S_ISVTX));
#endif
// Constants for the errors:
#ifdef EACCES
AssPRec(tmp, RNamName("EACCES" ), INTOBJ_INT((Int )EACCES));
#endif
#ifdef EEXIST
AssPRec(tmp, RNamName("EEXIST" ), INTOBJ_INT((Int )EEXIST));
#endif
#ifdef EFAULT
AssPRec(tmp, RNamName("EFAULT" ), INTOBJ_INT((Int )EFAULT));
#endif
#ifdef EISDIR
AssPRec(tmp, RNamName("EISDIR" ), INTOBJ_INT((Int )EISDIR));
#endif
#ifdef ELOOP
AssPRec(tmp, RNamName("ELOOP" ), INTOBJ_INT((Int )ELOOP));
#endif
#ifdef EMFILE
AssPRec(tmp, RNamName("EMFILE" ), INTOBJ_INT((Int )EMFILE));
#endif
#ifdef ENAMETOOLONG
AssPRec(tmp, RNamName("ENAMETOOLONG" ), INTOBJ_INT((Int )ENAMETOOLONG));
#endif
#ifdef ENFILE
AssPRec(tmp, RNamName("ENFILE" ), INTOBJ_INT((Int )ENFILE));
#endif
#ifdef ENODEV
AssPRec(tmp, RNamName("ENODEV" ), INTOBJ_INT((Int )ENODEV));
#endif
#ifdef ENOENT
AssPRec(tmp, RNamName("ENOENT" ), INTOBJ_INT((Int )ENOENT));
#endif
#ifdef ENOMEM
AssPRec(tmp, RNamName("ENOMEM" ), INTOBJ_INT((Int )ENOMEM));
#endif
#ifdef ENOSPC
AssPRec(tmp, RNamName("ENOSPC" ), INTOBJ_INT((Int )ENOSPC));
#endif
#ifdef ENOTDIR
AssPRec(tmp, RNamName("ENOTDIR" ), INTOBJ_INT((Int )ENOTDIR));
#endif
#ifdef ENXIO
AssPRec(tmp, RNamName("ENXIO" ), INTOBJ_INT((Int )ENXIO));
#endif
#ifdef EOVERFLOW
AssPRec(tmp, RNamName("EOVERFLOW" ), INTOBJ_INT((Int )EOVERFLOW));
#endif
#ifdef EPERM
AssPRec(tmp, RNamName("EPERM" ), INTOBJ_INT((Int )EPERM));
#endif
#ifdef EROFS
AssPRec(tmp, RNamName("EROFS" ), INTOBJ_INT((Int )EROFS));
#endif
#ifdef ETXTBSY
AssPRec(tmp, RNamName("ETXTBSY" ), INTOBJ_INT((Int )ETXTBSY));
#endif
#ifdef EAGAIN
AssPRec(tmp, RNamName("EAGAIN" ), INTOBJ_INT((Int )EAGAIN));
#endif
#ifdef EBADF
AssPRec(tmp, RNamName("EBADF" ), INTOBJ_INT((Int )EBADF));
#endif
#ifdef EINTR
AssPRec(tmp, RNamName("EINTR" ), INTOBJ_INT((Int )EINTR));
#endif
#ifdef EINVAL
AssPRec(tmp, RNamName("EINVAL" ), INTOBJ_INT((Int )EINVAL));
#endif
#ifdef EIO
AssPRec(tmp, RNamName("EIO" ), INTOBJ_INT((Int )EIO));
#endif
#ifdef EFBIG
AssPRec(tmp, RNamName("EFBIG" ), INTOBJ_INT((Int )EFBIG));
#endif
#ifdef ENOSPC
AssPRec(tmp, RNamName("ENOSPC" ), INTOBJ_INT((Int )ENOSPC));
#endif
#ifdef EPIPE
AssPRec(tmp, RNamName("EPIPE" ), INTOBJ_INT((Int )EPIPE));
#endif
#ifdef EBUSY
AssPRec(tmp, RNamName("EBUSY" ), INTOBJ_INT((Int )EBUSY));
#endif
#ifdef ESPIPE
AssPRec(tmp, RNamName("ESPIPE" ), INTOBJ_INT((Int )ESPIPE));
#endif
#ifdef EMLINK
AssPRec(tmp, RNamName("EMLINK" ), INTOBJ_INT((Int )EMLINK));
#endif
#ifdef EXDEV
AssPRec(tmp, RNamName("EXDEV" ), INTOBJ_INT((Int )EXDEV));
#endif
#ifdef ENOTEMPTY
AssPRec(tmp, RNamName("ENOTEMPTY" ), INTOBJ_INT((Int )ENOTEMPTY));
#endif
#ifdef EAFNOSUPPORT
AssPRec(tmp, RNamName("EAFNOSUPPORT" ), INTOBJ_INT((Int )EAFNOSUPPORT));
#endif
#ifdef ENOBUGS
AssPRec(tmp, RNamName("ENOBUGS" ), INTOBJ_INT((Int )ENOBUGS));
#endif
#ifdef EPROTONOSUPPORT
AssPRec(tmp, RNamName("EPROTONOSUPPORT" ),
INTOBJ_INT((Int )EPROTONOSUPPORT));
#endif
#ifdef ENOTSOCK
AssPRec(tmp, RNamName("ENOTSOCK" ), INTOBJ_INT((Int )ENOTSOCK));
#endif
#ifdef EADDRINUSE
AssPRec(tmp, RNamName("EADDRINUSE" ), INTOBJ_INT((Int )EADDRINUSE));
#endif
#ifdef EALREADY
AssPRec(tmp, RNamName("EALREADY" ), INTOBJ_INT((Int )EALREADY));
#endif
#ifdef ECONNREFUSED
AssPRec(tmp, RNamName("ECONNREFUSED" ), INTOBJ_INT((Int )ECONNREFUSED));
#endif
#ifdef EINPROGRESS
AssPRec(tmp, RNamName("EINPROGRESS" ), INTOBJ_INT((Int )EINPROGRESS));
#endif
#ifdef EISCONN
AssPRec(tmp, RNamName("EISCONN" ), INTOBJ_INT((Int )EISCONN));
#endif
#ifdef ETIMEDOUT
AssPRec(tmp, RNamName("ETIMEDOUT" ), INTOBJ_INT((Int )ETIMEDOUT));
#endif
#ifdef EOPNOTSUPP
AssPRec(tmp, RNamName("EOPNOTSUPP" ), INTOBJ_INT((Int )EOPNOTSUPP));
#endif
#ifdef EPROTO
AssPRec(tmp, RNamName("EPROTO" ), INTOBJ_INT((Int )EPROTO));
#endif
#ifdef ECONNABORTED
AssPRec(tmp, RNamName("ECONNABORTED" ), INTOBJ_INT((Int )ECONNABORTED));
#endif
#ifdef ECHILD
AssPRec(tmp, RNamName("ECHILD" ), INTOBJ_INT((Int )ECHILD));
#endif
#ifdef EWOULDBLOCK
AssPRec(tmp, RNamName("EWOULDBLOCK" ), INTOBJ_INT((Int )EWOULDBLOCK));
#endif
#ifdef HOST_NOT_FOUND
AssPRec(tmp, RNamName("HOST_NOT_FOUND" ), INTOBJ_INT((Int )HOST_NOT_FOUND));
#endif
#ifdef NO_ADDRESS
AssPRec(tmp, RNamName("NO_ADDRESS" ), INTOBJ_INT((Int )NO_ADDRESS));
#endif
#ifdef NO_DATA
AssPRec(tmp, RNamName("NO_DATA" ), INTOBJ_INT((Int )NO_DATA));
#endif
#ifdef NO_RECOVERY
AssPRec(tmp, RNamName("NO_RECOVERY" ), INTOBJ_INT((Int )NO_RECOVERY));
#endif
#ifdef TRY_AGAIN
AssPRec(tmp, RNamName("TRY_AGAIN" ), INTOBJ_INT((Int )TRY_AGAIN));
#endif
// Constants for networking:
#ifdef AF_APPLETALK
AssPRec(tmp, RNamName("AF_APPLETALK" ), INTOBJ_INT((Int )AF_APPLETALK));
#endif
#ifdef AF_ASH
AssPRec(tmp, RNamName("AF_ASH" ), INTOBJ_INT((Int )AF_ASH));
#endif
#ifdef AF_ATMPVC
AssPRec(tmp, RNamName("AF_ATMPVC" ), INTOBJ_INT((Int )AF_ATMPVC));
#endif
#ifdef AF_ATMSVC
AssPRec(tmp, RNamName("AF_ATMSVC" ), INTOBJ_INT((Int )AF_ATMSVC));
#endif
#ifdef AF_AX25
AssPRec(tmp, RNamName("AF_AX25" ), INTOBJ_INT((Int )AF_AX25));
#endif
#ifdef AF_BLUETOOTH
AssPRec(tmp, RNamName("AF_BLUETOOTH" ), INTOBJ_INT((Int )AF_BLUETOOTH));
#endif
#ifdef AF_BRIDGE
AssPRec(tmp, RNamName("AF_BRIDGE" ), INTOBJ_INT((Int )AF_BRIDGE));
#endif
#ifdef AF_DECnet
AssPRec(tmp, RNamName("AF_DECnet" ), INTOBJ_INT((Int )AF_DECnet));
#endif
#ifdef AF_ECONET
AssPRec(tmp, RNamName("AF_ECONET" ), INTOBJ_INT((Int )AF_ECONET));
#endif
#ifdef AF_FILE
AssPRec(tmp, RNamName("AF_FILE" ), INTOBJ_INT((Int )AF_FILE));
#endif
#ifdef AF_INET
AssPRec(tmp, RNamName("AF_INET" ), INTOBJ_INT((Int )AF_INET));
#endif
#ifdef AF_INET6
AssPRec(tmp, RNamName("AF_INET6" ), INTOBJ_INT((Int )AF_INET6));
#endif
#ifdef AF_IPX
AssPRec(tmp, RNamName("AF_IPX" ), INTOBJ_INT((Int )AF_IPX));
#endif
#ifdef AF_IRDA
AssPRec(tmp, RNamName("AF_IRDA" ), INTOBJ_INT((Int )AF_IRDA));
#endif
#ifdef AF_KEY
AssPRec(tmp, RNamName("AF_KEY" ), INTOBJ_INT((Int )AF_KEY));
#endif
#ifdef AF_LOCAL
AssPRec(tmp, RNamName("AF_LOCAL" ), INTOBJ_INT((Int )AF_LOCAL));
#endif
#ifdef AF_MAX
AssPRec(tmp, RNamName("AF_MAX" ), INTOBJ_INT((Int )AF_MAX));
#endif
#ifdef AF_NETBEUI
AssPRec(tmp, RNamName("AF_NETBEUI" ), INTOBJ_INT((Int )AF_NETBEUI));
#endif
#ifdef AF_NETLINK
AssPRec(tmp, RNamName("AF_NETLINK" ), INTOBJ_INT((Int )AF_NETLINK));
#endif
#ifdef AF_NETROM
AssPRec(tmp, RNamName("AF_NETROM" ), INTOBJ_INT((Int )AF_NETROM));
#endif
#ifdef AF_PACKET
AssPRec(tmp, RNamName("AF_PACKET" ), INTOBJ_INT((Int )AF_PACKET));
#endif
#ifdef AF_PPPOX
AssPRec(tmp, RNamName("AF_PPPOX" ), INTOBJ_INT((Int )AF_PPPOX));
#endif
#ifdef AF_ROSE
AssPRec(tmp, RNamName("AF_ROSE" ), INTOBJ_INT((Int )AF_ROSE));
#endif
#ifdef AF_ROUTE
AssPRec(tmp, RNamName("AF_ROUTE" ), INTOBJ_INT((Int )AF_ROUTE));
#endif
#ifdef AF_SECURITY
AssPRec(tmp, RNamName("AF_SECURITY" ), INTOBJ_INT((Int )AF_SECURITY));
#endif
#ifdef AF_SNA
AssPRec(tmp, RNamName("AF_SNA" ), INTOBJ_INT((Int )AF_SNA));
#endif
#ifdef AF_UNIX
AssPRec(tmp, RNamName("AF_UNIX" ), INTOBJ_INT((Int )AF_UNIX));
#endif
#ifdef AF_UNSPEC
AssPRec(tmp, RNamName("AF_UNSPEC" ), INTOBJ_INT((Int )AF_UNSPEC));
#endif
#ifdef AF_WANPIPE
AssPRec(tmp, RNamName("AF_WANPIPE" ), INTOBJ_INT((Int )AF_WANPIPE));
#endif
#ifdef AF_X25
AssPRec(tmp, RNamName("AF_X25" ), INTOBJ_INT((Int )AF_X25));
#endif
#ifdef PF_APPLETALK
AssPRec(tmp, RNamName("PF_APPLETALK" ), INTOBJ_INT((Int )PF_APPLETALK));
#endif
#ifdef PF_ASH
AssPRec(tmp, RNamName("PF_ASH" ), INTOBJ_INT((Int )PF_ASH));
#endif
#ifdef PF_ATMPVC
AssPRec(tmp, RNamName("PF_ATMPVC" ), INTOBJ_INT((Int )PF_ATMPVC));
#endif
#ifdef PF_ATMSVC
AssPRec(tmp, RNamName("PF_ATMSVC" ), INTOBJ_INT((Int )PF_ATMSVC));
#endif
#ifdef PF_AX25
AssPRec(tmp, RNamName("PF_AX25" ), INTOBJ_INT((Int )PF_AX25));
#endif
#ifdef PF_BLUETOOTH
AssPRec(tmp, RNamName("PF_BLUETOOTH" ), INTOBJ_INT((Int )PF_BLUETOOTH));
#endif
#ifdef PF_BRIDGE
AssPRec(tmp, RNamName("PF_BRIDGE" ), INTOBJ_INT((Int )PF_BRIDGE));
#endif
#ifdef PF_DECnet
AssPRec(tmp, RNamName("PF_DECnet" ), INTOBJ_INT((Int )PF_DECnet));
#endif
#ifdef PF_ECONET
AssPRec(tmp, RNamName("PF_ECONET" ), INTOBJ_INT((Int )PF_ECONET));
#endif
#ifdef PF_FILE
AssPRec(tmp, RNamName("PF_FILE" ), INTOBJ_INT((Int )PF_FILE));
#endif
#ifdef PF_INET
AssPRec(tmp, RNamName("PF_INET" ), INTOBJ_INT((Int )PF_INET));
#endif
#ifdef PF_INET6
AssPRec(tmp, RNamName("PF_INET6" ), INTOBJ_INT((Int )PF_INET6));
#endif
#ifdef PF_IPX
AssPRec(tmp, RNamName("PF_IPX" ), INTOBJ_INT((Int )PF_IPX));
#endif
#ifdef PF_IRDA
AssPRec(tmp, RNamName("PF_IRDA" ), INTOBJ_INT((Int )PF_IRDA));
#endif
#ifdef PF_KEY
AssPRec(tmp, RNamName("PF_KEY" ), INTOBJ_INT((Int )PF_KEY));
#endif
#ifdef PF_LOCAL
AssPRec(tmp, RNamName("PF_LOCAL" ), INTOBJ_INT((Int )PF_LOCAL));
#endif
#ifdef PF_MAX
AssPRec(tmp, RNamName("PF_MAX" ), INTOBJ_INT((Int )PF_MAX));
#endif
#ifdef PF_NETBEUI
AssPRec(tmp, RNamName("PF_NETBEUI" ), INTOBJ_INT((Int )PF_NETBEUI));
#endif
#ifdef PF_NETLINK
AssPRec(tmp, RNamName("PF_NETLINK" ), INTOBJ_INT((Int )PF_NETLINK));
#endif
#ifdef PF_NETROM
AssPRec(tmp, RNamName("PF_NETROM" ), INTOBJ_INT((Int )PF_NETROM));
#endif
#ifdef PF_PACKET
--> --------------------
--> maximum size reached
--> --------------------
quality 94%
¤ Dauer der Verarbeitung: 0.35 Sekunden
(vorverarbeitet)
¤
*© Formatika GbR, Deutschland