summaryrefslogtreecommitdiff
path: root/Modules/posixmodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/posixmodule.c')
-rw-r--r--Modules/posixmodule.c424
1 files changed, 291 insertions, 133 deletions
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 07d12e74e6..a0f34e5aa1 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -1,5 +1,5 @@
/***********************************************************
-Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
+Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands.
All Rights Reserved
@@ -24,78 +24,115 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* POSIX module implementation */
-#ifdef AMOEBA
-#define NO_LSTAT
-#define SYSV
+#ifdef _M_IX86
+#define NT
+/* NT may be defined externally as well. If it is defined, the module is
+ actually called 'nt', not 'posix', and some functions don't exist. */
#endif
-#ifdef __sgi
-#define DO_PG
-#endif
-
-#ifdef _NEXT_SOURCE
-#define mode_t int
-#define NO_UNAME
-#endif
+#include "allobjects.h"
+#include "modsupport.h"
+#include "ceval.h"
-#include <signal.h>
#include <string.h>
-#include <setjmp.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#ifdef DO_TIMES
-#include <sys/times.h>
-#include <sys/param.h>
#include <errno.h>
-#endif
-#ifdef SYSV
-
-#define UTIME_STRUCT 1
-#include <dirent.h>
-#define direct dirent
-#ifdef i386
-#define mode_t int
-#endif
-
-#else /* !SYSV */
-
-#include <sys/dir.h>
+#ifndef macintosh
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
-#endif /* !SYSV */
+#include "mytime.h" /* For clock_t on some systems */
-#ifndef NO_UNISTD
-#include <unistd.h> /* Take this out and hope the best if it doesn't exist */
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
#endif
-#include "allobjects.h"
-#include "modsupport.h"
-#include "ceval.h"
-
-#ifdef _SEQUENT_
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
-#else /* _SEQUENT_ */
-/* XXX Aren't these always declared in unistd.h? */
+#else /* !HAVE_UNISTD_H */
+
+#ifdef macintosh
+#include "macdefs.h"
+#else
extern int mkdir PROTO((const char *, mode_t));
extern int chdir PROTO((const char *));
extern int rmdir PROTO((const char *));
extern int chmod PROTO((const char *, mode_t));
-extern char *getcwd(); /* No PROTO((char *, int)) -- non portable */
+extern int chown PROTO((const char *, uid_t, gid_t));
+extern char *getcwd PROTO((char *, int));
extern char *strerror PROTO((int));
extern int link PROTO((const char *, const char *));
extern int rename PROTO((const char *, const char *));
extern int stat PROTO((const char *, struct stat *));
extern int unlink PROTO((const char *));
extern int pclose PROTO((FILE *));
-#endif /* !_SEQUENT_ */
-#ifdef NO_LSTAT
-#define lstat stat
-#else
-extern int lstat PROTO((const char *, struct stat *));
+#ifdef HAVE_SYMLINK
extern int symlink PROTO((const char *, const char *));
#endif
+#ifdef HAVE_LSTAT
+extern int lstat PROTO((const char *, struct stat *));
+#endif
+#endif /* macintosh */
+#endif /* !HAVE_UNISTD_H */
+
+#if 1
+/* XXX These are for SunOS4.1.3 but shouldn't hurt elsewhere */
+extern int rename();
+extern int pclose();
+extern int lstat();
+extern int symlink();
+#endif
+#ifdef HAVE_UTIME_H
+#include <utime.h>
+#endif
+
+#ifdef HAVE_SYS_TIMES_H
+#include <sys/times.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifdef HAVE_SYS_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 1024
+#endif
+
+/* unistd.h defines _POSIX_VERSION on POSIX.1 systems. */
+#if defined(DIRENT) || defined(_POSIX_VERSION)
+#include <dirent.h>
+#define NLENGTH(dirent) (strlen((dirent)->d_name))
+#else /* not (DIRENT or _POSIX_VERSION) */
+#define dirent direct
+#define NLENGTH(dirent) ((dirent)->d_namlen)
+#ifdef SYSNDIR
+#include <sys/ndir.h>
+#endif /* SYSNDIR */
+#ifdef SYSDIR
+#include <sys/dir.h>
+#endif /* SYSDIR */
+#ifdef NDIR
+#include <ndir.h>
+#endif /* NDIR */
+#endif /* not (DIRENT or _POSIX_VERSION) */
+
+#ifdef NT
+#include <direct.h>
+#include <io.h>
+#include <process.h>
+#include <windows.h>
+#define popen _popen
+#endif /* NT */
+
+#ifdef OS2
+#include <io.h>
+#endif
/* Return a dictionary corresponding to the POSIX environment table */
@@ -195,6 +232,25 @@ posix_strint(args, func)
}
static object *
+posix_strintint(args, func)
+ object *args;
+ int (*func) FPROTO((const char *, int, int));
+{
+ char *path;
+ int i,i2;
+ int res;
+ if (!getargs(args, "(sii)", &path, &i, &i2))
+ return NULL;
+ BGN_SAVE
+ res = (*func)(path, i, i2);
+ END_SAVE
+ if (res < 0)
+ return posix_error();
+ INCREF(None);
+ return None;
+}
+
+static object *
posix_do_stat(self, args, statfunc)
object *self;
object *args;
@@ -242,6 +298,16 @@ posix_chmod(self, args)
return posix_strint(args, chmod);
}
+#ifdef HAVE_CHOWN
+static object *
+posix_chown(self, args)
+ object *self;
+ object *args;
+{
+ return posix_strintint(args, chown);
+}
+#endif
+
static object *
posix_getcwd(self, args)
object *self;
@@ -259,6 +325,7 @@ posix_getcwd(self, args)
return newstringobject(buf);
}
+#ifdef HAVE_LINK
static object *
posix_link(self, args)
object *self;
@@ -266,7 +333,64 @@ posix_link(self, args)
{
return posix_2str(args, link);
}
+#endif
+
+#ifdef NT
+static object *
+posix_listdir(self, args)
+ object *self;
+ object *args;
+{
+ char *name;
+ int len;
+ object *d, *v;
+ HANDLE hFindFile;
+ WIN32_FIND_DATA FileData;
+ char namebuf[MAX_PATH+5];
+
+ if (!getargs(args, "s#", &name, &len))
+ return NULL;
+ if (len >= MAX_PATH) {
+ err_setstr(ValueError, "path too long");
+ return NULL;
+ }
+ strcpy(namebuf, name);
+ if (namebuf[len-1] != '/' && namebuf[len-1] != '\\')
+ namebuf[len++] = '/';
+ strcpy(namebuf + len, "*.*");
+
+ if ((d = newlistobject(0)) == NULL)
+ return NULL;
+
+ hFindFile = FindFirstFile(namebuf, &FileData);
+ if (hFindFile == INVALID_HANDLE_VALUE) {
+ errno = GetLastError();
+ return posix_error();
+ }
+ do {
+ v = newstringobject(FileData.cFileName);
+ if (v == NULL) {
+ DECREF(d);
+ d = NULL;
+ break;
+ }
+ if (addlistitem(d, v) != 0) {
+ DECREF(v);
+ DECREF(d);
+ d = NULL;
+ break;
+ }
+ DECREF(v);
+ } while (FindNextFile(hFindFile, &FileData) == TRUE);
+
+ if (FindClose(hFindFile) == FALSE) {
+ errno = GetLastError();
+ return posix_error();
+ }
+ return d;
+}
+#else /* ! NT */
static object *
posix_listdir(self, args)
object *self;
@@ -275,7 +399,7 @@ posix_listdir(self, args)
char *name;
object *d, *v;
DIR *dirp;
- struct direct *ep;
+ struct dirent *ep;
if (!getargs(args, "s", &name))
return NULL;
BGN_SAVE
@@ -308,6 +432,7 @@ posix_listdir(self, args)
return d;
}
+#endif /* ! NT */
static object *
posix_mkdir(self, args)
@@ -317,6 +442,7 @@ posix_mkdir(self, args)
return posix_strint(args, mkdir);
}
+#ifdef HAVE_NICE
static object *
posix_nice(self, args)
object *self;
@@ -331,21 +457,7 @@ posix_nice(self, args)
return posix_error();
return newintobject((long) value);
}
-
-#if i386 && ! _SEQUENT_
-int
-rename(from, to)
- char *from;
- char *to;
-{
- int status;
- /* XXX Shouldn't this unlink the destination first? */
- status = link(from, to);
- if (status != 0)
- return status;
- return unlink(from);
-}
-#endif /* i386 && ! _SEQUENT_ */
+#endif /* HAVE_NICE */
static object *
posix_rename(self, args)
@@ -408,11 +520,7 @@ posix_unlink(self, args)
return posix_1str(args, unlink);
}
-#ifndef NO_UNAME
-#include <sys/utsname.h>
-
-extern int uname PROTO((struct utsname *));
-
+#ifdef HAVE_UNAME
static object *
posix_uname(self, args)
object *self;
@@ -435,11 +543,7 @@ posix_uname(self, args)
u.version,
u.machine);
}
-#endif /* NO_UNAME */
-
-#ifdef UTIME_STRUCT
-#include <utime.h>
-#endif
+#endif /* HAVE_UNAME */
static object *
posix_utime(self, args)
@@ -449,12 +553,11 @@ posix_utime(self, args)
char *path;
int res;
-#ifdef UTIME_STRUCT
+#ifdef HAVE_UTIME_H
struct utimbuf buf;
#define ATIME buf.actime
#define MTIME buf.modtime
#define UTIME_ARG &buf
-
#else
time_t buf[2];
#define ATIME buf[0]
@@ -532,8 +635,12 @@ posix_execv(self, args)
}
argvlist[argc] = NULL;
+#ifdef BAD_EXEC_PROTOTYPES
+ execv(path, (const char **) argvlist);
+#else
execv(path, argvlist);
-
+#endif
+
/* If we get here it's definitely an error */
DEL(argvlist);
@@ -614,7 +721,12 @@ posix_execve(self, args)
}
envlist[envc] = 0;
+
+#ifdef BAD_EXEC_PROTOTYPES
+ execve(path, (const char **)argvlist, envlist);
+#else
execve(path, argvlist, envlist);
+#endif
/* If we get here it's definitely an error */
@@ -684,6 +796,7 @@ posix_getpid(self, args)
return newintobject((long)getpid());
}
+#ifdef HAVE_GETPGRP
static object *
posix_getpgrp(self, args)
object *self;
@@ -691,13 +804,15 @@ posix_getpgrp(self, args)
{
if (!getnoarg(args))
return NULL;
-#ifdef SYSV
- return newintobject((long)getpgrp());
-#else
+#ifdef GETPGRP_HAVE_ARG
return newintobject((long)getpgrp(0));
+#else
+ return newintobject((long)getpgrp());
#endif
}
+#endif /* HAVE_GETPGRP */
+#ifdef HAVE_SETPGRP
static object *
posix_setpgrp(self, args)
object *self;
@@ -705,16 +820,18 @@ posix_setpgrp(self, args)
{
if (!getnoarg(args))
return NULL;
-#ifdef SYSV
- if (setpgrp() < 0)
-#else
+#ifdef GETPGRP_HAVE_ARG
if (setpgrp(0, 0) < 0)
+#else
+ if (setpgrp() < 0)
#endif
return posix_error();
INCREF(None);
return None;
}
+#endif /* HAVE_SETPGRP */
+
static object *
posix_getppid(self, args)
object *self;
@@ -763,12 +880,10 @@ posix_popen(self, args)
END_SAVE
if (fp == NULL)
return posix_error();
- /* From now on, ignore SIGPIPE and let the error checking
- do the work. */
- (void) signal(SIGPIPE, SIG_IGN);
return newopenfileobject(fp, name, mode, pclose);
}
+#ifdef HAVE_SETUID
static object *
posix_setuid(self, args)
object *self;
@@ -782,7 +897,9 @@ posix_setuid(self, args)
INCREF(None);
return None;
}
+#endif
+#ifdef HAVE_SETGID
static object *
posix_setgid(self, args)
object *self;
@@ -796,17 +913,14 @@ posix_setgid(self, args)
INCREF(None);
return None;
}
+#endif
+#ifdef HAVE_WAITPID
static object *
posix_waitpid(self, args)
object *self;
object *args;
{
-#ifdef NO_WAITPID
- err_setstr(PosixError,
- "posix.waitpid() not supported on this system");
- return NULL;
-#else
int pid, options, sts;
if (!getargs(args, "(ii)", &pid, &options))
return NULL;
@@ -817,8 +931,8 @@ posix_waitpid(self, args)
return posix_error();
else
return mkvalue("ii", pid, sts);
-#endif
}
+#endif /* HAVE_WAITPID */
static object *
posix_wait(self, args)
@@ -826,8 +940,6 @@ posix_wait(self, args)
object *args;
{
int pid, sts;
- if (args != NULL)
- return posix_waitpid(self, args); /* BW compat */
BGN_SAVE
pid = wait(&sts);
END_SAVE
@@ -842,19 +954,20 @@ posix_lstat(self, args)
object *self;
object *args;
{
+#ifdef HAVE_LSTAT
return posix_do_stat(self, args, lstat);
+#else /* !HAVE_LSTAT */
+ return posix_do_stat(self, args, stat);
+#endif /* !HAVE_LSTAT */
}
+#ifdef HAVE_READLINK
static object *
posix_readlink(self, args)
object *self;
object *args;
{
-#ifdef NO_LSTAT
- err_setstr(PosixError, "readlink not implemented on this system");
- return NULL;
-#else
- char buf[1024]; /* XXX Should use MAXPATHLEN */
+ char buf[MAXPATHLEN];
char *path;
int n;
if (!getargs(args, "s", &path))
@@ -865,25 +978,23 @@ posix_readlink(self, args)
if (n < 0)
return posix_error();
return newsizedstringobject(buf, n);
-#endif
}
+#endif /* HAVE_READLINK */
+#ifdef HAVE_SYMLINK
static object *
posix_symlink(self, args)
object *self;
object *args;
{
-#ifdef NO_LSTAT
- err_setstr(PosixError, "symlink not implemented on this system");
- return NULL;
-#else
return posix_2str(args, symlink);
-#endif
}
+#endif /* HAVE_SYMLINK */
-
-#ifdef DO_TIMES
-
+#ifdef HAVE_TIMES
+#ifndef HZ
+#define HZ 60 /* Universal constant :-) */
+#endif
static object *
posix_times(self, args)
object *self;
@@ -903,11 +1014,9 @@ posix_times(self, args)
(double)t.tms_cutime / HZ,
(double)t.tms_cstime / HZ);
}
+#endif /* HAVE_TIMES */
-#endif /* DO_TIMES */
-
-#ifdef DO_PG
-
+#ifdef HAVE_SETSID
static object *
posix_setsid(self, args)
object *self;
@@ -920,7 +1029,9 @@ posix_setsid(self, args)
INCREF(None);
return None;
}
+#endif /* HAVE_SETSID */
+#ifdef HAVE_SETPGID
static object *
posix_setpgid(self, args)
object *self;
@@ -934,7 +1045,9 @@ posix_setpgid(self, args)
INCREF(None);
return None;
}
+#endif /* HAVE_SETPGID */
+#ifdef HAVE_TCGETPGRP
static object *
posix_tcgetpgrp(self, args)
object *self;
@@ -948,7 +1061,9 @@ posix_tcgetpgrp(self, args)
return posix_error();
return newintobject((long)pgid);
}
+#endif /* HAVE_TCGETPGRP */
+#ifdef HAVE_TCSETPGRP
static object *
posix_tcsetpgrp(self, args)
object *self;
@@ -962,8 +1077,7 @@ posix_tcsetpgrp(self, args)
INCREF(None);
return None;
}
-
-#endif /* DO_PG */
+#endif /* HAVE_TCSETPGRP */
/* Functions acting on file descriptors */
@@ -1150,7 +1264,6 @@ posix_fdopen(self, args)
return posix_error();
/* From now on, ignore SIGPIPE and let the error checking
do the work. */
- (void) signal(SIGPIPE, SIG_IGN);
return newopenfileobject(fp, "(fdopen)", mode, fclose);
}
@@ -1174,49 +1287,84 @@ posix_pipe(self, args)
static struct methodlist posix_methods[] = {
{"chdir", posix_chdir},
{"chmod", posix_chmod},
+#ifdef HAVE_CHOWN
+ {"chown", posix_chown},
+#endif
{"getcwd", posix_getcwd},
+#ifdef HAVE_LINK
{"link", posix_link},
+#endif
{"listdir", posix_listdir},
{"lstat", posix_lstat},
{"mkdir", posix_mkdir},
+#ifdef HAVE_NICE
{"nice", posix_nice},
+#endif
+#ifdef HAVE_READLINK
{"readlink", posix_readlink},
+#endif
{"rename", posix_rename},
{"rmdir", posix_rmdir},
{"stat", posix_stat},
+#ifdef HAVE_SYMLINK
{"symlink", posix_symlink},
+#endif
{"system", posix_system},
{"umask", posix_umask},
-#ifndef NO_UNAME
+#ifdef HAVE_UNAME
{"uname", posix_uname},
#endif
{"unlink", posix_unlink},
+#ifndef NT
{"utime", posix_utime},
-#ifdef DO_TIMES
+#endif /* ! NT */
+#ifdef HAVE_TIMES
{"times", posix_times},
#endif
{"_exit", posix__exit},
{"execv", posix_execv},
{"execve", posix_execve},
+#ifndef NT
{"fork", posix_fork},
{"getegid", posix_getegid},
{"geteuid", posix_geteuid},
{"getgid", posix_getgid},
+#endif /* ! NT */
{"getpid", posix_getpid},
+#ifdef HAVE_GETPGRP
{"getpgrp", posix_getpgrp},
+#endif
+#ifndef NT
{"getppid", posix_getppid},
{"getuid", posix_getuid},
{"kill", posix_kill},
+#endif /* ! NT */
{"popen", posix_popen},
+#ifdef HAVE_SETUID
{"setuid", posix_setuid},
+#endif
+#ifdef HAVE_SETGID
{"setgid", posix_setgid},
+#endif
+#ifdef HAVE_SETPGRP
{"setpgrp", posix_setpgrp},
+#endif
+#ifndef NT
{"wait", posix_wait},
+#endif /* ! NT */
+#ifdef HAVE_WAITPID
{"waitpid", posix_waitpid},
-#ifdef DO_PG
+#endif
+#ifdef HAVE_SETSID
{"setsid", posix_setsid},
+#endif
+#ifdef HAVE_SETPGID
{"setpgid", posix_setpgid},
+#endif
+#ifdef HAVE_TCGETPGRP
{"tcgetpgrp", posix_tcgetpgrp},
+#endif
+#ifdef HAVE_TCSETPGRP
{"tcsetpgrp", posix_tcsetpgrp},
#endif
{"open", posix_open},
@@ -1228,12 +1376,35 @@ static struct methodlist posix_methods[] = {
{"write", posix_write},
{"fstat", posix_fstat},
{"fdopen", posix_fdopen},
+#ifndef NT
{"pipe", posix_pipe},
+#endif /* ! NT */
{NULL, NULL} /* Sentinel */
};
+#ifdef NT
+void
+initnt()
+{
+ object *m, *d, *v;
+
+ m = initmodule("nt", posix_methods);
+ d = getmoduledict(m);
+
+ /* Initialize nt.environ dictionary */
+ v = convertenviron();
+ if (v == NULL || dictinsert(d, "environ", v) != 0)
+ fatal("can't define nt.environ");
+ DECREF(v);
+
+ /* Initialize nt.error exception */
+ PosixError = newstringobject("nt.error");
+ if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
+ fatal("can't define nt.error");
+}
+#else /* ! NT */
void
initposix()
{
@@ -1253,17 +1424,4 @@ initposix()
if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
fatal("can't define posix.error");
}
-
-
-/* Function used elsewhere to get a file's modification time */
-
-long
-getmtime(path)
- char *path;
-{
- struct stat st;
- if (stat(path, &st) != 0)
- return -1;
- else
- return st.st_mtime;
-}
+#endif /* ! NT */