******************************************************************/
-/* Interface to execute compiled code */
-/* This header depends on "compile.h" */
-
-object *eval_code PROTO((codeobject *, object *, object *, object *));
+/* Interface to random parts in ceval.c */
object *call_object PROTO((object *, object *));
void printtraceback PROTO((FILE *));
void flushline PROTO((void));
+
+
+/* Interface for threads.
+
+ A module that plans to do a blocking system call (or something else
+ that lasts a long time and doesn't touch Python data) can allow other
+ threads to run as follows:
+
+ ...preparations here...
+ BGN_SAVE
+ ...blocking system call here...
+ END_SAVE
+ ...interpretr result here...
+
+ The BGN_SAVE/END_SAVE pair expands to a {}-surrounded block.
+ To leave the block in the middle (e.g., with return), you must insert
+ a line containing RET_SAVE before the return, e.g.
+
+ if (...premature_exit...) {
+ RET_SAVE
+ err_errno(IOError);
+ return NULL;
+ }
+
+ An alternative is:
+
+ RET_SAVE
+ if (...premature_exit...) {
+ err_errno(IOError);
+ return NULL;
+ }
+ RES_SAVE
+
+ For convenience, that the value of 'errno' is restored across
+ END_SAVE and RET_SAVE.
+
+ WARNING: NEVER NEST CALLS TO BGN_SAVE AND END_SAVE!!!
+
+ The function init_save_thread() should be called only from
+ initthread() in "threadmodule.c".
+
+ Note that not yet all candidates have been converted to use this
+ mechanism!
+*/
+
+extern void init_save_thread PROTO((void));
+extern void *save_thread PROTO((void));
+extern void restore_thread PROTO((void *));
+
+#ifdef USE_THREAD
+
+#define BGN_SAVE { \
+ void *_save; \
+ _save = save_thread();
+#define RET_SAVE restore_thread(_save);
+#define RES_SAVE _save = save_thread();
+#define END_SAVE restore_thread(_save); \
+ }
+
+#else /* !USE_THREAD */
+
+#define BGN_SAVE {
+#define RET_SAVE
+#define RES_SAVE
+#define END_SAVE }
+
+#endif /* !USE_THREAD */
--- /dev/null
+/***********************************************************
+Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
+Netherlands.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+/* Interface to execute compiled code */
+
+object *eval_code PROTO((codeobject *, object *, object *, object *));
#include "allobjects.h"
#include "import.h"
#include "modsupport.h"
-#include "compile.h"
#include "ceval.h"
#define NCALLBACKS 8
print 'initgl()'
print '{'
print '\tinitmodule("gl", gl_methods);'
+print '\t/* Initialize GL and don\'t go in the background */'
+print '\tforeground();'
+print '\tnoport();'
+print '\twinopen("");'
print '}'
#include "import.h"
#include "modsupport.h"
#include "structmember.h"
-
-/* #include "ceval.h" */
-extern object *call_object(object *, object *);
+#include "ceval.h"
/* Generic Forms Objects */
#include "allobjects.h"
#include "modsupport.h"
+#include "ceval.h"
extern char *strerror PROTO((int));
int (*func) FPROTO((const char *));
{
char *path1;
+ int res;
if (!getstrarg(args, &path1))
return NULL;
- if ((*func)(path1) < 0)
+ BGN_SAVE
+ res = (*func)(path1);
+ END_SAVE
+ if (res < 0)
return posix_error();
INCREF(None);
return None;
int (*func) FPROTO((const char *, const char *));
{
char *path1, *path2;
+ int res;
if (!getstrstrarg(args, &path1, &path2))
return NULL;
- if ((*func)(path1, path2) < 0)
+ BGN_SAVE
+ res = (*func)(path1, path2);
+ END_SAVE
+ if (res < 0)
return posix_error();
INCREF(None);
return None;
{
char *path;
int i;
+ int res;
if (!getstrintarg(args, &path, &i))
return NULL;
- if ((*func)(path, i) < 0)
+ BGN_SAVE
+ res = (*func)(path, i);
+ END_SAVE
+ if (res < 0)
return posix_error();
INCREF(None);
return None;
struct stat st;
char *path;
object *v;
+ int res;
if (!getstrarg(args, &path))
return NULL;
- if ((*statfunc)(path, &st) != 0)
+ BGN_SAVE
+ res = (*statfunc)(path, &st);
+ END_SAVE
+ if (res != 0)
return posix_error();
v = newtupleobject(10);
if (v == NULL)
object *args;
{
char buf[1026];
+ char *res;
extern char *getcwd PROTO((char *, int));
if (!getnoarg(args))
return NULL;
- if (getcwd(buf, sizeof buf) == NULL)
+ BGN_SAVE
+ res = getcwd(buf, sizeof buf);
+ END_SAVE
+ if (res == NULL)
return posix_error();
return newstringobject(buf);
}
struct direct *ep;
if (!getstrarg(args, &name))
return NULL;
- if ((dirp = opendir(name)) == NULL)
+ BGN_SAVE
+ if ((dirp = opendir(name)) == NULL) {
+ RET_SAVE
return posix_error();
+ }
if ((d = newlistobject(0)) == NULL) {
closedir(dirp);
+ RET_SAVE
return NULL;
}
while ((ep = readdir(dirp)) != NULL) {
DECREF(v);
}
closedir(dirp);
+ END_SAVE
#endif /* !MSDOS */
return d;
object *args;
{
char *command;
- int sts;
+ long sts;
if (!getstrarg(args, &command))
return NULL;
+ BGN_SAVE
sts = system(command);
- return newintobject((long)sts);
+ END_SAVE
+ return newintobject(sts);
}
#ifndef MSDOS
extern int uname PROTO((struct utsname *));
struct utsname u;
object *v;
+ int res;
if (!getnoarg(args))
return NULL;
- if (uname(&u) < 0)
+ BGN_SAVE
+ res = uname(&u);
+ END_SAVE
+ if (res < 0)
return posix_error();
v = newtupleobject(5);
if (v == NULL)
object *args;
{
char *path;
+ int res;
#ifdef UTIME_STRUCT
struct utimbuf buf;
if (!getargs(args, "(s(ll))", &path, &ATIME, &MTIME))
return NULL;
- if (utime(path, UTIME_ARG) < 0)
+ BGN_SAVE
+ res = utime(path, UTIME_ARG);
+ END_SAVE
+ if (res < 0)
return posix_error();
INCREF(None);
return None;
FILE *fp;
if (!getargs(args, "(ss)", &name, &mode))
return NULL;
+ BGN_SAVE
fp = popen(name, mode);
+ END_SAVE
if (fp == NULL)
return posix_error();
/* From now on, ignore SIGPIPE and let the error checking
{
object *v;
int pid, sts;
- if (args == NULL)
+ if (args == NULL) {
+ BGN_SAVE
pid = wait(&sts);
+ END_SAVE
+ }
else {
#ifdef NO_WAITPID
err_setstr(PosixError,
int options;
if (!getintintarg(args, &pid, &options))
return NULL;
+ BGN_SAVE
pid = waitpid(pid, &sts, options);
+ END_SAVE
#endif
}
if (pid == -1)
int n;
if (!getstrarg(args, &path))
return NULL;
+ BGN_SAVE
n = readlink(path, buf, (int) sizeof buf);
+ END_SAVE
if (n < 0)
return posix_error();
return newsizedstringobject(buf, n);
#include "allobjects.h"
#include "modsupport.h"
-#include "compile.h"
#include "ceval.h"
#include "myselect.h"
if ( omax > max ) max = omax;
if ( emax > max ) max = emax;
+ BGN_SAVE
n = select(max, &ifdset, &ofdset, &efdset, tvp);
+ END_SAVE
if ( n < 0 ) {
err_errno(SelectError);
/* Socket module */
-/* XXX Ought to fix getStr*arg calls to use getargs(args, "s#", ...) */
-
/*
This module provides an interface to Berkeley socket IPC.
#include "allobjects.h"
#include "modsupport.h"
+#include "ceval.h"
#include "myselect.h" /* Implies <sys/types.h>, <sys/time.h>, <sys/param.h> */
((long) d3 << 8) | ((long) d4 << 0));
return 4;
}
+ BGN_SAVE
hp = gethostbyname(name);
+ END_SAVE
if (hp == NULL) {
err_setstr(SocketError, "host not found");
return -1;
case AF_UNIX:
{
static struct sockaddr_un addr;
- object *path;
+ char *path;
int len;
- if (!getStrarg(args, &path))
+ if (!getargs(args, "s#", &path, &len))
return 0;
- if ((len = getstringsize(path)) > sizeof addr.sun_path) {
+ if (len > sizeof addr.sun_path) {
err_setstr(SocketError, "AF_UNIX path too long");
return 0;
}
addr.sun_family = AF_UNIX;
- memcpy(addr.sun_path, getstringvalue(path), len);
+ memcpy(addr.sun_path, path, len);
*addr_ret = (struct sockaddr *) &addr;
*len_ret = len + sizeof addr.sun_family;
return 1;
case AF_INET:
{
static struct sockaddr_in addr;
- object *host;
+ char *host;
int port;
- if (!getStrintarg(args, &host, &port))
+ if (!getargs(args, "(si)", &host, &port))
return 0;
- if (setipaddr(getstringvalue(host), &addr) < 0)
+ if (setipaddr(host, &addr) < 0)
return 0;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
return NULL;
if (!getsockaddrlen(s, &addrlen))
return NULL;
+ BGN_SAVE
newfd = accept(s->sock_fd, (struct sockaddr *) addrbuf, &addrlen);
+ END_SAVE
if (newfd < 0)
return socket_error();
/* Create the new object with unspecified family,
{
int flag;
int res;
- if (!getintarg(args, &flag))
+ if (!getargs(args, "i", &flag))
return NULL;
res = setsockopt(s->sock_fd, SOL_SOCKET, SO_BROADCAST,
&flag, sizeof flag);
{
struct sockaddr *addr;
int addrlen;
+ int res;
if (!getsockaddrarg(s, args, &addr, &addrlen))
return NULL;
- if (bind(s->sock_fd, addr, addrlen) < 0)
+ BGN_SAVE
+ res = bind(s->sock_fd, addr, addrlen);
+ END_SAVE
+ if (res < 0)
return socket_error();
INCREF(None);
return None;
{
if (!getnoarg(args))
return NULL;
+ BGN_SAVE
(void) close(s->sock_fd);
+ END_SAVE
s->sock_fd = -1;
INCREF(None);
return None;
{
struct sockaddr *addr;
int addrlen;
+ int res;
if (!getsockaddrarg(s, args, &addr, &addrlen))
return NULL;
- if (connect(s->sock_fd, addr, addrlen) < 0)
+ BGN_SAVE
+ res = connect(s->sock_fd, addr, addrlen);
+ END_SAVE
+ if (res < 0)
return socket_error();
INCREF(None);
return None;
object *args;
{
int backlog;
+ int res;
if (!getintarg(args, &backlog))
return NULL;
- if (listen(s->sock_fd, backlog) < 0)
+ BGN_SAVE
+ res = listen(s->sock_fd, backlog);
+ END_SAVE
+ if (res < 0)
return socket_error();
INCREF(None);
return None;
object *args;
{
extern int fclose PROTO((FILE *));
- object *mode;
+ char *mode;
int fd;
FILE *fp;
- if (!getStrarg(args, &mode))
+ if (!getargs(args, "s", &mode))
return NULL;
if ((fd = dup(s->sock_fd)) < 0 ||
- (fp = fdopen(fd, getstringvalue(mode))) == NULL)
+ (fp = fdopen(fd, mode)) == NULL)
return socket_error();
- return newopenfileobject(fp, "<socket>", getstringvalue(mode), fclose);
+ return newopenfileobject(fp, "<socket>", mode, fclose);
}
buf = newsizedstringobject((char *) 0, len);
if (buf == NULL)
return NULL;
+ BGN_SAVE
n = recv(s->sock_fd, getstringvalue(buf), len, flags);
+ END_SAVE
if (n < 0)
return socket_error();
if (resizestring(&buf, n) < 0)
int addrlen, len, n;
if (!getintarg(args, &len))
return NULL;
+ if (!getsockaddrlen(s, &addrlen))
+ return NULL;
buf = newsizedstringobject((char *) 0, len);
- addrlen = sizeof addrbuf;
+ BGN_SAVE
n = recvfrom(s->sock_fd, getstringvalue(buf), len, 0,
addrbuf, &addrlen);
+ END_SAVE
if (n < 0)
return socket_error();
if (resizestring(&buf, n) < 0)
sockobject *s;
object *args;
{
- object *buf;
+ char *buf;
int len, n, flags;
- if (!getStrintarg(args, &buf, &flags)) {
+ if (!getargs(args, "(s#i)", &buf, &len, &flags)) {
err_clear();
- if (!getStrarg(args, &buf))
+ if (!getargs(args, "s#", &buf, &len))
return NULL;
flags = 0;
}
- len = getstringsize(buf);
- n = send(s->sock_fd, getstringvalue(buf), len, flags);
+ BGN_SAVE
+ n = send(s->sock_fd, buf, len, flags);
+ END_SAVE
if (n < 0)
return socket_error();
INCREF(None);
sockobject *s;
object *args;
{
- object *buf;
+ object *addro;
+ char *buf;
struct sockaddr *addr;
int addrlen, len, n;
if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2) {
err_badarg();
return NULL;
}
- if (!getStrarg(gettupleitem(args, 0), &buf) ||
- !getsockaddrarg(s, gettupleitem(args, 1), &addr, &addrlen))
+ if (!getargs(args, "(s#O)", &buf, &len, &addro) ||
+ !getsockaddrarg(s, addro, &addr, &addrlen))
return NULL;
- len = getstringsize(buf);
- n = sendto(s->sock_fd, getstringvalue(buf), len, 0,
- addr, addrlen);
+ BGN_SAVE
+ n = sendto(s->sock_fd, buf, len, 0, addr, addrlen);
+ END_SAVE
if (n < 0)
return socket_error();
INCREF(None);
object *args;
{
int how;
+ int res;
if (!getintarg(args, &how))
return NULL;
- if (shutdown(s->sock_fd, how) < 0)
+ BGN_SAVE
+ res = shutdown(s->sock_fd, how);
+ END_SAVE
+ if (res < 0)
return socket_error();
INCREF(None);
return None;
object *args;
{
char buf[1024];
+ int res;
if (!getnoarg(args))
return NULL;
- if (gethostname(buf, (int) sizeof buf - 1) < 0)
+ BGN_SAVE
+ res = gethostname(buf, (int) sizeof buf - 1);
+ END_SAVE
+ if (res < 0)
return socket_error();
buf[sizeof buf - 1] = '\0';
return newstringobject(buf);
}
+
+
/* Python interface to gethostbyname(name). */
/*ARGSUSED*/
{
object *name;
struct sockaddr_in addrbuf;
- if (!getStrarg(args, &name))
+ if (!getargs(args, "s", &name))
return NULL;
- if (setipaddr(getstringvalue(name), &addrbuf) < 0)
+ if (setipaddr(name, &addrbuf) < 0)
return NULL;
return makeipaddr(&addrbuf);
}
object *self;
object *args;
{
- object *name, *proto;
+ char *name, *proto;
struct servent *sp;
- if (!getStrStrarg(args, &name, &proto))
+ if (!getargs(args, "(ss)", &name, &proto))
return NULL;
- sp = getservbyname(getstringvalue(name), getstringvalue(proto));
+ BGN_SAVE
+ sp = getservbyname(name, proto);
+ END_SAVE
if (sp == NULL) {
err_setstr(SocketError, "service/proto not found");
return NULL;
return NULL;
proto = 0;
}
+ BGN_SAVE
fd = socket(family, type, proto);
+ END_SAVE
if (fd < 0)
return socket_error();
s = newsockobject(fd, family, type, proto);
*/
#include "allobjects.h"
-
#include "modsupport.h"
+#include "ceval.h"
#include "stdwin.h"
+#ifdef USE_THREAD
+
+#include "thread.h"
+
+static type_lock StdwinLock; /* Lock held when interpreter not locked */
+
+#define BGN_STDWIN BGN_SAVE acquire_lock(StdwinLock, 1);
+#define RET_STDWIN release_lock(StdwinLock); RET_SAVE
+#define END_STDWIN release_lock(StdwinLock); END_SAVE
+
+#else
+
+#define BGN_STDWIN BGN_SAVE
+#define RET_STDWIN RET_SAVE
+#define END_STDWIN END_SAVE
+
+#endif
+
static object *StdwinError; /* Exception stdwin.error */
/* Window and menu object types declared here because of forward references */
return NULL;
}
again:
+ BGN_STDWIN
if (poll) {
if (!wpollevent(&e)) {
+ RET_STDWIN
INCREF(None);
return None;
}
}
else
wgetevent(&e);
+ END_STDWIN
if (e.type == WE_COMMAND && e.u.command == WC_CANCEL) {
/* Turn keyboard interrupts into exceptions */
err_set(KeyboardInterrupt);
return NULL;
strncpy(buf, dflt, sizeof buf);
buf[sizeof buf - 1] = '\0';
+ BGN_STDWIN
ret = waskfile(prompt, buf, sizeof buf, new);
+ END_STDWIN
if (!ret) {
err_set(KeyboardInterrupt);
return NULL;
int new, ret;
if (!getstrintarg(args, &prompt, &new))
return NULL;
+ BGN_STDWIN
ret = waskync(prompt, new);
+ END_STDWIN
if (ret < 0) {
err_set(KeyboardInterrupt);
return NULL;
return NULL;
strncpy(buf, dflt, sizeof buf);
buf[sizeof buf - 1] = '\0';
+ BGN_STDWIN
ret = waskstr(prompt, buf, sizeof buf);
+ END_STDWIN
if (!ret) {
err_set(KeyboardInterrupt);
return NULL;
char *msg;
if (!getstrarg(args, &msg))
return NULL;
+ BGN_STDWIN
wmessage(msg);
+ END_STDWIN
INCREF(None);
return None;
}
StdwinError = newstringobject("stdwin.error");
if (StdwinError == NULL || dictinsert(d, "error", StdwinError) != 0)
fatal("can't define stdwin.error");
+#ifdef USE_THREAD
+ StdwinLock = allocate_lock();
+ if (StdwinLock == NULL)
+ fatal("can't allocate stdwin lock");
+#endif
}
#include "allobjects.h"
#include "modsupport.h"
-#include "compile.h"
#include "ceval.h"
#include "thread.h"
-extern void init_save_thread PROTO((void));
-extern void* save_thread PROTO((void));
-extern void restore_thread PROTO((void *));
-
object *ThreadError;
lockobject *self;
object *args;
{
- void *save;
int i;
if (args != NULL) {
else
i = 1;
- save = save_thread();
-
+ BGN_SAVE
i = acquire_lock(self->lock_lock, i);
-
- restore_thread(save);
+ END_SAVE
if (args == NULL) {
INCREF(None);
if (res == NULL) {
fprintf(stderr, "Unhandled exception in thread:\n");
print_error(); /* From pythonmain.c */
- fprintf(stderr, "Exiting the entire program\n");
- goaway(1);
}
(void) save_thread();
exit_thread();
{
if (!getnoarg(args))
return NULL;
- return newlockobject();
+ return (object *) newlockobject();
}
static struct methodlist thread_methods[] = {
/* Time module */
#include "allobjects.h"
-
#include "modsupport.h"
+#include "ceval.h"
#include "sigtype.h"
object *self;
object *args;
{
- void *save, *save_thread(), restore_thread();
- int secs;
+ long secs;
SIGTYPE (*sigsave)() = 0; /* Initialized to shut lint up */
- if (!getintarg(args, &secs))
+ if (!getargs(args, "l", &secs))
return NULL;
- save = save_thread();
+ BGN_SAVE
if (setjmp(sleep_intr)) {
- restore_thread(save);
+ RET_SAVE
signal(SIGINT, sigsave);
err_set(KeyboardInterrupt);
return NULL;
sigsave = signal(SIGINT, SIG_IGN);
if (sigsave != (SIGTYPE (*)()) SIG_IGN)
signal(SIGINT, sleep_catcher);
- sleep(secs);
- restore_thread(save);
+#ifdef BSD_TIME
+ longsleep(secs);
+#else
+ sleep((int)secs);
+#endif
+ END_SAVE
signal(SIGINT, sigsave);
INCREF(None);
return None;
object *self;
object *args;
{
- void *save, *save_thread(), restore_thread();
long msecs;
SIGTYPE (*sigsave)();
if (!getlongarg(args, &msecs))
return NULL;
- save = save_thread();
+ BGN_SAVE
if (setjmp(sleep_intr)) {
- restore_thread(save);
+ RET_SAVE
signal(SIGINT, sigsave);
err_set(KeyboardInterrupt);
return NULL;
if (sigsave != (SIGTYPE (*)()) SIG_IGN)
signal(SIGINT, sleep_catcher);
millisleep(msecs);
- restore_thread(save);
+ END_SAVE
signal(SIGINT, sigsave);
INCREF(None);
return None;
#define MacTicks (* (long *)0x16A)
#ifdef THINK_C_3_0
-sleep(msecs)
- int msecs;
+sleep(secs)
+ int secs;
{
register long deadline;
- deadline = MacTicks + msecs * 60;
+ deadline = MacTicks + mecs * 60;
while (MacTicks < deadline) {
if (intrcheck())
sleep_catcher(SIGINT);
if (gettimeofday(&t, &tz) != 0)
return -1;
return t.tv_sec*1000 + t.tv_usec/1000;
-
}
millisleep(msecs)
(void) select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
}
+longsleep(secs)
+ long secs;
+{
+ struct timeval t;
+ t.tv_sec = secs;
+ t.tv_usec = 0;
+ (void) select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
+}
+
#endif /* BSD_TIME */
#include "allobjects.h"
#include "modsupport.h"
+#include "ceval.h"
#define BUF(v) GETSTRINGVALUE((stringobject *)v)
}
else
#endif
- f->f_fp = fopen(name, mode);
+ {
+ BGN_SAVE
+ f->f_fp = fopen(name, mode);
+ END_SAVE
+ }
if (f->f_fp == NULL) {
err_errno(IOError);
DECREF(f);
file_dealloc(f)
fileobject *f;
{
- if (f->f_fp != NULL && f->f_close != NULL)
+ if (f->f_fp != NULL && f->f_close != NULL) {
+ BGN_SAVE
(*f->f_close)(f->f_fp);
+ END_SAVE
+ }
if (f->f_name != NULL)
DECREF(f->f_name);
if (f->f_mode != NULL)
int sts = 0;
if (!getnoarg(args))
return NULL;
- errno = 0;
if (f->f_fp != NULL) {
- if (f->f_close != NULL)
+ if (f->f_close != NULL) {
+ BGN_SAVE
+ errno = 0;
sts = (*f->f_close)(f->f_fp);
+ END_SAVE
+ }
f->f_fp = NULL;
}
if (sts == EOF)
{
long offset;
int whence;
+ int ret;
if (f->f_fp == NULL)
return err_closed();
if (!getargs(args, "(li)", &offset, &whence))
return NULL;
}
+ BGN_SAVE
errno = 0;
- if (fseek(f->f_fp, offset, whence) != 0) {
+ ret = fseek(f->f_fp, offset, whence);
+ END_SAVE
+ if (ret != 0) {
err_errno(IOError);
clearerr(f->f_fp);
return NULL;
return err_closed();
if (!getnoarg(args))
return NULL;
+ BGN_SAVE
errno = 0;
offset = ftell(f->f_fp);
+ END_SAVE
if (offset == -1L) {
err_errno(IOError);
clearerr(f->f_fp);
fileobject *f;
object *args;
{
+ int res;
+
if (f->f_fp == NULL)
return err_closed();
if (!getnoarg(args))
return NULL;
+ BGN_SAVE
errno = 0;
- if (fflush(f->f_fp) != 0) {
+ res = fflush(f->f_fp);
+ END_SAVE
+ if (res != 0) {
err_errno(IOError);
clearerr(f->f_fp);
return NULL;
fileobject *f;
object *args;
{
+ long res;
if (f->f_fp == NULL)
return err_closed();
if (!getnoarg(args))
return NULL;
- return newintobject((long)isatty((int)fileno(f->f_fp)));
+ BGN_SAVE
+ res = isatty((int)fileno(f->f_fp));
+ END_SAVE
+ return newintobject(res);
}
static object *
if (v == NULL)
return NULL;
n1 = 0;
+ BGN_SAVE
for (;;) {
n3 = fread(BUF(v)+n1, 1, n2-n1, f->f_fp);
/* XXX Error check? */
break;
if (n == 0) {
n2 = n1 + BUFSIZ;
+ RET_SAVE
if (resizestring(&v, n2) < 0)
return NULL;
+ RES_SAVE
}
}
+ END_SAVE
if (n1 != n2)
resizestring(&v, n1);
return v;
fileobject *f;
int n;
{
- void *save, *save_thread(), restore_thread();
register FILE *fp;
register int c;
register char *buf, *end;
buf = BUF(v);
end = buf + n2;
- save = save_thread();
+ BGN_SAVE
for (;;) {
if ((c = getc(fp)) == EOF) {
clearerr(fp);
if (intrcheck()) {
- restore_thread(save);
+ RET_SAVE
DECREF(v);
err_set(KeyboardInterrupt);
return NULL;
}
if (n < 0 && buf == BUF(v)) {
- restore_thread(save);
+ RET_SAVE
DECREF(v);
err_setstr(EOFError,
"EOF when reading a line");
break;
n1 = n2;
n2 += 1000;
- restore_thread(save);
+ RET_SAVE
if (resizestring(&v, n2) < 0)
return NULL;
- save = save_thread();
+ RES_SAVE
buf = BUF(v) + n1;
end = BUF(v) + n2;
}
}
- restore_thread(save);
+ END_SAVE
n1 = buf - BUF(v);
if (n1 != n2)
if (!getargs(args, "s#", &s, &n))
return NULL;
f->f_softspace = 0;
+ BGN_SAVE
errno = 0;
n2 = fwrite(s, 1, n, f->f_fp);
+ END_SAVE
if (n2 != n) {
err_errno(IOError);
clearerr(f->f_fp);
#include "allobjects.h"
#include "modsupport.h"
-#include "compile.h" /* Needed by ceval.h */
-#include "ceval.h" /* For call_object() */
+#include "ceval.h"
object *
newlistobject(size)
#include "bltinmodule.h"
#include "import.h"
#include "pythonrun.h"
-#include "compile.h" /* For ceval.h */
#include "ceval.h"
#include "modsupport.h"
"execfile arguments must be filename[,dict[,dict]]");
return NULL;
}
+ BGN_SAVE
fp = fopen(getstringvalue(str), "r");
+ END_SAVE
if (fp == NULL) {
err_setstr(IOError, "execfile cannot open the file argument");
return NULL;
}
w = run_file(fp, getstringvalue(str), file_input, globals, locals);
+ BGN_SAVE
fclose(fp);
+ END_SAVE
return w;
}
}
m = add_module("__main__");
d = getmoduledict(m);
+ BGN_SAVE
while ((c = getc(in)) != EOF && (c == ' ' || c == '\t'))
;
ungetc(c, in);
+ END_SAVE
return run_file(in, "<stdin>", expr_input, d, d);
}
#include "sysmodule.h"
#include "compile.h"
#include "frameobject.h"
+#include "eval.h"
#include "ceval.h"
#include "opcode.h"
#include "bltinmodule.h"
static frameobject *current_frame;
-
-/* Interface for threads.
-
- A module that plans to do a blocking system call (or something else
- that lasts a long time and doesn't touch Python data) can allow other
- threads to run as follows:
-
- void *x;
-
- ...preparations here...
- x = save_thread();
- ...blocking system call here...
- restore_thread(x);
- ...interpretr result here...
-
- For convenience, that the value of 'errno' is restored across the
- the call to restore_thread().
-
- The function init_save_thread() should be called only from
- initthread() in "threadmodule.c".
-
- Note that not yet all candidates have been converted to use this
- mechanism!
-*/
-
#ifdef USE_THREAD
+
#include <errno.h>
#include "thread.h"
+
static type_lock interpreter_lock;
void
init_save_thread()
{
-#ifdef USE_THREAD
if (interpreter_lock)
fatal("2nd call to init_save_thread");
interpreter_lock = allocate_lock();
acquire_lock(interpreter_lock, 1);
-#endif
}
+
#endif
+/* Functions save_thread and restore_thread are always defined so
+ dynamically loaded modules needn't be compiled separately for use
+ with and without threads: */
+
void *
save_thread()
{
#include "pythonrun.h"
#include "marshal.h"
#include "compile.h"
-#include "ceval.h"
+#include "eval.h"
#include "osdefs.h"
extern int verbose; /* Defined in pythonmain.c */
#include "allobjects.h"
-extern char *getpythonpath();
-
extern int debugging; /* Needed by parser.c */
extern int verbose; /* Needed by import.c */
#include "errcode.h"
#include "sysmodule.h"
#include "compile.h"
+#include "eval.h"
#include "ceval.h"
#include "pythonrun.h"
#include "import.h"
-#ifdef USE_THREAD
-extern void *save_thread();
-#endif
-
extern char *getpythonpath();
extern grammar gram; /* From graminit.c */
FILE *fp;
char *filename;
{
- void *save, *save_thread(), restore_thread();
object *m, *d, *v, *w;
node *n;
char *ps1, *ps2;
w = NULL;
ps2 = "";
}
- save = save_thread();
+ BGN_SAVE
err = parsefile(fp, filename, &gram, single_input, ps1, ps2, &n);
- restore_thread(save);
+ END_SAVE
XDECREF(v);
XDECREF(w);
if (err == E_EOF)
int start;
node **n_ret;
{
- return parsefile(fp, filename, &gram, start,
+ int ret;
+ BGN_SAVE
+ ret = parsefile(fp, filename, &gram, start,
(char *)0, (char *)0, n_ret);
+ END_SAVE
+ return ret;
}
/* Simplified interface to parsestring */
int sts;
{
flushline();
+
+#ifdef USE_THREAD
+
+ /* Other threads may still be active, so skip most of the
+ cleanup actions usually done (these are mostly for
+ debugging anyway). */
+
+ (void *) save_thread();
+ donecalls();
+ exit_prog(sts);
+
+#else /* USE_THREAD */
/* XXX Call doneimport() before donecalls(), since donecalls()
calls wdone(), and doneimport() may close windows */
}
#endif /* TRACE_REFS */
-#ifdef USE_THREAD
- (void) save_thread();
- exit_prog(sts);
-#else
exit(sts);
-#endif
+#endif /* USE_THREAD */
/*NOTREACHED*/
}
#include <lwp/lwp.h>
#include <lwp/stackdep.h>
-#define STACKSIZE 1000 /* stacksize for a thread */
+#define STACKSIZE 16000 /* stacksize for a thread */
#define NSTACKS 2 /* # stacks to be put in cache initialy */
struct lock {
exit(0);
#ifdef __sgi
exiting = 1;
- exit(0);
+ _exit(0);
#endif
#ifdef SOLARIS
thread_exit();
#ifdef DEBUG
printf("exiting in exit_sig\n");
#endif
- exit(exit_status);
+ _exit(exit_status);
}
}
#endif
exiting = 1;
do_exit = 1;
exit_status = status;
- exit(status);
+ _exit(status);
#endif
#ifdef sun
pod_exit(status);