diff --git a/NT/tools/lib b/NT/tools/lib index d99d5b048c37e640648805b43d2473e58e6fc205..7b908b97821d409e73ecaaff1428409681c7bbdc 100644 --- a/NT/tools/lib +++ b/NT/tools/lib @@ -1,5 +1,5 @@ CLEANUP=yes -DEBUG=yes +DEBUG=no if [ $DEBUG = yes ]; then set -x diff --git a/bin/test_pike.pike b/bin/test_pike.pike index f05c9eff6e07ce940000ff7e92d8db8165549c93..edd8a137f12108270bca16c239f42cb56ee90905 100755 --- a/bin/test_pike.pike +++ b/bin/test_pike.pike @@ -1,6 +1,6 @@ #!/usr/local/bin/pike -/* $Id: test_pike.pike,v 1.4 1997/05/31 22:03:40 grubba Exp $ */ +/* $Id: test_pike.pike,v 1.5 1998/01/03 07:11:24 hubbe Exp $ */ #include <simulate.h> @@ -12,7 +12,7 @@ int main(int argc, string *argv) { int e, verbose, successes, errors, t, check; - string *tests; + string *tests,tmp; program testprogram; int start, fail, mem; int loop=1; @@ -81,21 +81,27 @@ int main(int argc, string *argv) perror("Unknown argument: "+opt+".\n"); exit(1); } - tests=(read_bytes(argv[e])||"")/"\n....\n"; + tmp=read_bytes(argv[e]); + if(!tmp) + { + perror("Failed to read test file, errno="+errno()+".\n"); + exit(1); + } } } - if(!tests) + if(!tmp) { - tests=(clone((program)"/precompiled/file","stdin")->read(0x7fffffff)||"")/"\n....\n"; + tmp=Stdio.stdin->read(0x7fffffff); + if(!tmp) + { + perror("Failed to read test file, errno="+errno()+".\n"); + exit(1); + } } - if(!tests) - { - perror("Failed to read test file!\n"); - exit(1); - } + tests=tmp/"\n....\n"; tests=tests[0..sizeof(tests)-2]; while(loop--) diff --git a/lib/modules/Stdio.pmod b/lib/modules/Stdio.pmod index c972fa8a8c3bd1312aa28c77bdc06e2ae12b3e84..5f07e008886ee0756349c928213e9c7ddd94c01d 100644 --- a/lib/modules/Stdio.pmod +++ b/lib/modules/Stdio.pmod @@ -193,7 +193,8 @@ string read_bytes(string filename,void|int start,void|int len) case 2: len=0x7fffffff; case 3: - f->seek(start); + if(start) + f->seek(start); } ret=f->read(len); f->close(); diff --git a/src/fdlib.c b/src/fdlib.c index 99c68614ebd4a1494b9be0ae5391e86bf62d4e7c..d958ba98a546062a67cf7e87e592635b3c00bde8 100644 --- a/src/fdlib.c +++ b/src/fdlib.c @@ -1,4 +1,5 @@ #include "fdlib.h" +#include <math.h> #ifdef HAVE_WINSOCK_H @@ -11,6 +12,8 @@ long da_handle[MAX_OPEN_FILEDESCRIPTORS]; static int fd_type[MAX_OPEN_FILEDESCRIPTORS]; int first_free_handle; +#define FDDEBUG(X) + void fd_init() { int e; @@ -20,14 +23,14 @@ void fd_init() { fatal("No winsock available.\n"); } -/* fprintf(stderr,"Using %s\n",wsadata.szDescription); */ + FDDEBUG(fprintf(stderr,"Using %s\n",wsadata.szDescription)); fd_type[0]=FD_CONSOLE; - da_handle[0]=GetStdHandle(STD_INPUT_HANDLE); + da_handle[0]=(long)GetStdHandle(STD_INPUT_HANDLE); fd_type[1]=FD_CONSOLE; - da_handle[1]=GetStdHandle(STD_OUTPUT_HANDLE); + da_handle[1]=(long)GetStdHandle(STD_OUTPUT_HANDLE); fd_type[2]=FD_CONSOLE; - da_handle[2]=GetStdHandle(STD_ERROR_HANDLE); + da_handle[2]=(long)GetStdHandle(STD_ERROR_HANDLE); first_free_handle=3; for(e=3;e<MAX_OPEN_FILEDESCRIPTORS-1;e++) @@ -46,6 +49,7 @@ FD fd_open(char *file, int open_mode, int create_mode) FD fd; DWORD omode,cmode,amode; omode=0; + FDDEBUG(fprintf(stderr,"fd_open(%s,0x%x,%o)\n",file,open_mode,create_mode)); if(first_free_handle == FD_NO_MORE_FREE) { errno=EMFILE; @@ -101,10 +105,13 @@ FD fd_open(char *file, int open_mode, int create_mode) return -1; } + fd=first_free_handle; first_free_handle=fd_type[fd]; fd_type[fd]=FD_FILE; - da_handle[fd]=x; + da_handle[fd]=(long)x; + + FDDEBUG(fprintf(stderr,"Opened %s file as %d (%d)\n",file,fd,x)); return fd; } @@ -128,7 +135,9 @@ FD fd_socket(int domain, int type, int proto) fd=first_free_handle; first_free_handle=fd_type[fd]; fd_type[fd]=FD_SOCKET; - da_handle[fd]=(HANDLE)s; + da_handle[fd]=(long)s; + + FDDEBUG(fprintf(stderr,"New socket: %d (%d)\n",fd,s)); return fd; } @@ -154,21 +163,26 @@ FD fd_accept(FD fd, struct sockaddr *addr, int *addrlen) return -1; } - fd=first_free_handle; - first_free_handle=fd_type[fd]; - fd_type[fd]=FD_SOCKET; - da_handle[fd]=(HANDLE)s; - return fd; + new_fd=first_free_handle; + first_free_handle=fd_type[new_fd]; + fd_type[new_fd]=FD_SOCKET; + da_handle[new_fd]=(long)s; + + FDDEBUG(fprintf(stderr,"Accept on %d (%d) returned new socket: %d (%d)\n",fd,da_handle[fd],new_fd,s)); + + return new_fd; } #define SOCKFUN(NAME,X1,X2) \ int PIKE_CONCAT(fd_,NAME) X1 { int ret; \ + FDDEBUG(fprintf(stderr, #NAME " on %d (%d)\n",fd,da_handle[fd])); \ if(fd_type[fd] != FD_SOCKET) { \ errno=ENOTSUPP; \ return -1; \ } \ ret=NAME X2; \ if(ret == SOCKET_ERROR) errno=WSAGetLastError(); \ + FDDEBUG(fprintf(stderr, #NAME " returned %d (%d)\n",ret,errno)); \ return ret; \ } @@ -202,7 +216,8 @@ SOCKFUN1(listen, int) int fd_close(FD fd) { - if(!CloseHandle(da_handle[fd])) + FDDEBUG(fprintf(stderr,"Closing %d (%d)\n",fd,da_handle[fd])); + if(!CloseHandle((HANDLE)da_handle[fd])) { errno=GetLastError(); return -1; @@ -215,6 +230,7 @@ int fd_close(FD fd) long fd_write(FD fd, void *buf, long len) { DWORD ret; + FDDEBUG(fprintf(stderr,"Writing %d bytes to %d (%d)\n",len,fd,da_handle[fd])); switch(fd_type[fd]) { case FD_SOCKET: @@ -228,7 +244,7 @@ long fd_write(FD fd, void *buf, long len) case FD_CONSOLE: case FD_FILE: - if(!WriteFile(da_handle[fd], buf, len, &ret,0) && !ret) + if(!WriteFile((HANDLE)da_handle[fd], buf, len, &ret,0) && !ret) { errno=GetLastError(); return -1; @@ -241,27 +257,32 @@ long fd_write(FD fd, void *buf, long len) } } -long fd_read(FD fd, void *buf, long len) +long fd_read(FD fd, void *to, long len) { DWORD ret; + FDDEBUG(fprintf(stderr,"Reading %d bytes from %d (%d) to %lx\n",len,fd,da_handle[fd],(int)(char *)to)); switch(fd_type[fd]) { case FD_SOCKET: - ret=recv((SOCKET)da_handle[fd], buf, len, 0); + ret=recv((SOCKET)da_handle[fd], to, len, 0); if(ret<0) { errno=WSAGetLastError(); return -1; } + FDDEBUG(fprintf(stderr,"Read returned %ld\n",ret)); return ret; case FD_CONSOLE: case FD_FILE: - if(!ReadFile(da_handle[fd], buf, len, &ret,0) && !ret) + ret=0; + if(!ReadFile((HANDLE)da_handle[fd], to, len, &ret,0) && !ret) { errno=GetLastError(); + FDDEBUG(fprintf(stderr,"Read failed %d\n",errno)); return -1; } + FDDEBUG(fprintf(stderr,"Read returned %ld\n",ret)); return ret; default: @@ -288,22 +309,63 @@ long fd_lseek(FD fd, long pos, int where) return ret; } +static long convert_filetime_to_time_t(FILETIME tmp) +{ + double t; + t=tmp.dwHighDateTime * pow(2.0,32.0) + (double)tmp.dwLowDateTime; + t/=10000000.0; + t-=11644473600.0; + return (long)floor(t); +} + int fd_fstat(FD fd, struct stat *s) { + DWORD x; int ret; + FILETIME c,a,m; + FDDEBUG(fprintf(stderr,"fstat on %d (%d)\n",fd,da_handle[fd])); if(fd_type[fd]!=FD_FILE) { errno=ENOTSUPP; return -1; } - ret=fstat(da_handle[fd], s); - if(ret<0) + MEMSET(s, 0, sizeof(struct stat)); + s->st_nlink=1; + + switch(fd_type[fd]) { - errno=GetLastError(); - return -1; + case FD_SOCKET: + s->st_mode=S_IFSOCK; + break; + + default: + switch(GetFileType((HANDLE)da_handle[fd])) + { + default: + case FILE_TYPE_UNKNOWN: s->st_mode=0; break; + case FILE_TYPE_DISK: + s->st_mode=S_IFREG; + s->st_size=GetFileSize((HANDLE)da_handle[fd],&x); + if(x) + { + s->st_size=0x7fffffff; + } + if(!GetFileTime((HANDLE)da_handle[fd], &c, &a, &m)) + { + errno=GetLastError(); + return -1; + } + s->st_ctime=convert_filetime_to_time_t(c); + s->st_atime=convert_filetime_to_time_t(a); + s->st_mtime=convert_filetime_to_time_t(m); + break; + case FILE_TYPE_CHAR: s->st_mode=S_IFCHR; break; + case FILE_TYPE_PIPE: s->st_mode=S_IFFIFO; break; + } } - return ret; + s->st_mode |= 0666; + return 0; } int fd_select(int fds, FD_SET *a, FD_SET *b, FD_SET *c, struct timeval *t) @@ -340,16 +402,58 @@ int fd_ioctl(FD fd, int cmd, void *data) } -FD fd_dup(FD fd) +FD fd_dup(FD from) { - errno=ENOTSUPP; - return -1; + FD fd; + HANDLE x,p=GetCurrentProcess(); + if(!DuplicateHandle(p,(HANDLE)da_handle[from],p,&x,NULL,1,DUPLICATE_SAME_ACCESS)) + { + errno=GetLastError(); + return -1; + } + + fd=first_free_handle; + first_free_handle=fd_type[fd]; + fd_type[fd]=fd_type[from]; + da_handle[fd]=(long)x; + + FDDEBUG(fprintf(stderr,"Dup %d (%d) to %d (%d)\n",from,da_handle[from],fd,x)); + return fd; } FD fd_dup2(FD to, FD from) { - errno=ENOTSUPP; - return -1; + HANDLE x,p=GetCurrentProcess(); + if(!DuplicateHandle(p,(HANDLE)da_handle[from],p,&x,NULL,1,DUPLICATE_SAME_ACCESS)) + { + errno=GetLastError(); + return -1; + } + + if(fd_type[to] < FD_NO_MORE_FREE) + { + if(!CloseHandle((HANDLE)da_handle[to])) + { + errno=GetLastError(); + return -1; + } + }else{ + int *prev,next; + for(prev=&first_free_handle;(next=*prev) != FD_NO_MORE_FREE;prev=fd_type+next) + { + if(next==to) + { + *prev=fd_type[next]; + break; + } + } + } + fd_type[to]=fd_type[from]; + da_handle[to]=(long)x; + + FDDEBUG(fprintf(stderr,"Dup2 %d (%d) to %d (%d)\n",from,da_handle[from],to,x)); + + return to; } #endif diff --git a/src/fdlib.h b/src/fdlib.h index 1159c41d057fc7c8ca92798c77c11a4d3d47b87a..be123d7369b335fbea2655ccb9153284630d5d2c 100644 --- a/src/fdlib.h +++ b/src/fdlib.h @@ -15,6 +15,10 @@ #include <errno.h> #endif +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif + #ifdef HAVE_WINSOCK_H @@ -102,6 +106,10 @@ extern long da_handle[MAX_OPEN_FILEDESCRIPTORS]; #define fd_FD_ISSET(X,Y) FD_ISSET((SOCKET)da_handle[X],Y) #define fd_FD_ZERO(X) FD_ZERO(X) +#ifndef S_IFSOCK +#define S_IFSOCK 0140000 +#endif + #else diff --git a/src/modules/Image/font.c b/src/modules/Image/font.c index 4673c869ecffb2be16f2ca737038ff91712e048c..d22e2a161f7a7325f4d5bf9621fbae2e713de164 100644 --- a/src/modules/Image/font.c +++ b/src/modules/Image/font.c @@ -1,4 +1,4 @@ -/* $Id: font.c,v 1.23 1997/12/28 09:29:32 hubbe Exp $ */ +/* $Id: font.c,v 1.24 1998/01/03 07:12:40 hubbe Exp $ */ #include <config.h> #define SPACE_CHAR 'i' @@ -6,7 +6,7 @@ /* **! module Image **! note -**! $Id: font.c,v 1.23 1997/12/28 09:29:32 hubbe Exp $ +**! $Id: font.c,v 1.24 1998/01/03 07:12:40 hubbe Exp $ **! class font **! **! note @@ -94,6 +94,7 @@ Kerningtable types: #include "global.h" +#include "fdlib.h" #include <sys/types.h> #include <sys/stat.h> @@ -212,10 +213,10 @@ static INLINE int char_width(struct font *this, unsigned char c) } #ifndef HAVE_MMAP -static INLINE int my_read(int from, char *buf, int towrite) +static INLINE int my_read(int from, void *t, int towrite) { int res; - while((res = read(from, buf, towrite)) < 0) + while((res = fd_read(from, t, towrite)) < 0) { switch(errno) { @@ -235,7 +236,7 @@ static INLINE long file_size(int fd) { struct stat tmp; int res; - if((!fstat(fd, &tmp)) && + if((!fd_fstat(fd, &tmp)) && (tmp.st_mode & S_IFREG)) { return res = tmp.st_size; } @@ -300,29 +301,32 @@ void font_load(INT32 args) #ifdef FONT_DEBUG fprintf(stderr,"FONT open '%s'\n",sp[-args].u.string->str); #endif - fd = open(sp[-args].u.string->str,O_RDONLY); + fd = fd_open(sp[-args].u.string->str,fd_RDONLY,0); } while(fd < 0 && errno == EINTR); if (fd >= 0) { long size; - struct font *new; + struct font *new_font; size = file_size(fd); if (size > 0) { - new=THIS=(struct font *)xalloc(sizeof(struct font)); + new_font=THIS=(struct font *)xalloc(sizeof(struct font)); THREADS_ALLOW(); #ifdef HAVE_MMAP - new->mem = + new_font->mem = mmap(0,size,PROT_READ,MAP_SHARED,fd,0); - new->mmaped_size=size; + new_font->mmaped_size=size; #else - new->mem = malloc(size); - if ((new->mem) && (!my_read(fd,new->mem,size))) { - free(new->mem); - new->mem = NULL; + new_font->mem = malloc(size); +#ifdef FONT_DEBUG + fprintf(stderr,"FONT Malloced %p (%d)\n",new_font->mem,size); +#endif + if ((new_font->mem) && (!my_read(fd,new_font->mem,size))) { + free(new_font->mem); + new_font->mem = NULL; } #endif THREADS_DISALLOW(); @@ -366,18 +370,18 @@ void font_load(INT32 args) THIS->chars=ntohl(fh->chars); - new=malloc(sizeof(struct font)+ + new_font=malloc(sizeof(struct font)+ sizeof(struct _char)*(THIS->chars-1)); - new->mem=THIS->mem; + new_font->mem=THIS->mem; #ifdef HAVE_MMAP - new->mmaped_size=THIS->mmaped_size; + new_font->mmaped_size=THIS->mmaped_size; #endif - new->chars=THIS->chars; - new->xspacing_scale = 1.0; - new->yspacing_scale = 1.0; - new->justification = J_LEFT; + new_font->chars=THIS->chars; + new_font->xspacing_scale = 1.0; + new_font->yspacing_scale = 1.0; + new_font->justification = J_LEFT; free(THIS); - THIS=new; + THIS=new_font; THIS->height=ntohl(fh->height); THIS->baseline=ntohl(fh->baseline); @@ -400,7 +404,7 @@ void font_load(INT32 args) fprintf(stderr,"FONT failed on char %02xh %d '%c'\n", i,i,i); #endif - free_font_struct(new); + free_font_struct(new_font); THIS=NULL; pop_n_elems(args); push_int(0); @@ -409,7 +413,7 @@ void font_load(INT32 args) } - close(fd); + fd_close(fd); pop_n_elems(args); THISOBJ->refs++; push_object(THISOBJ); /* success */ @@ -435,7 +439,7 @@ void font_load(INT32 args) #ifdef FONT_DEBUG else fprintf(stderr,"FONT size failure\n"); #endif - close(fd); + fd_close(fd); } /* fd failure */ #ifdef FONT_DEBUG else fprintf(stderr,"FONT fd failure\n"); diff --git a/src/modules/files/efuns.c b/src/modules/files/efuns.c index 71e4afe495d1ba95e88a3d088e4296ef2e5f604c..7a1cfba574149b082d723b204010362043d0a3f2 100644 --- a/src/modules/files/efuns.c +++ b/src/modules/files/efuns.c @@ -4,6 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" +#include "fdlib.h" #include "interpret.h" #include "svalue.h" #include "stralloc.h" diff --git a/src/modules/files/file.c b/src/modules/files/file.c index 2953bf0776e05aed10f5db171b8b180b6889e744..9daad37195613623cba995b831c5f3bd7d0657d3 100644 --- a/src/modules/files/file.c +++ b/src/modules/files/file.c @@ -6,7 +6,7 @@ #define READ_BUFFER 8192 #include "global.h" -RCSID("$Id: file.c,v 1.63 1998/01/02 01:06:33 hubbe Exp $"); +RCSID("$Id: file.c,v 1.64 1998/01/03 07:13:05 hubbe Exp $"); #include "fdlib.h" #include "interpret.h" #include "svalue.h" @@ -260,14 +260,14 @@ static int map(int flags) ret=0; switch(flags & (FILE_READ|FILE_WRITE)) { - case FILE_READ: ret=O_RDONLY; break; - case FILE_WRITE: ret=O_WRONLY; break; - case FILE_READ | FILE_WRITE: ret=O_RDWR; break; + case FILE_READ: ret=fd_RDONLY; break; + case FILE_WRITE: ret=fd_WRONLY; break; + case FILE_READ | FILE_WRITE: ret=fd_RDWR; break; } - if(flags & FILE_APPEND) ret|=O_APPEND; - if(flags & FILE_CREATE) ret|=O_CREAT; - if(flags & FILE_TRUNC) ret|=O_TRUNC; - if(flags & FILE_EXCLUSIVE) ret|=O_EXCL; + if(flags & FILE_APPEND) ret|=fd_APPEND; + if(flags & FILE_CREATE) ret|=fd_CREAT; + if(flags & FILE_TRUNC) ret|=fd_TRUNC; + if(flags & FILE_EXCLUSIVE) ret|=fd_EXCL; return ret; } @@ -295,7 +295,7 @@ static struct pike_string *do_read(int fd, do{ int fd=FD; THREADS_ALLOW(); - i=read(fd, str->str+bytes_read, r); + i=fd_read(fd, str->str+bytes_read, r); THREADS_DISALLOW(); check_signals(0,0,0); @@ -350,7 +350,7 @@ static struct pike_string *do_read(int fd, buf = low_make_buf_space(try_read, &b); THREADS_ALLOW(); - i=read(fd, buf, try_read); + i=fd_read(fd, buf, try_read); THREADS_DISALLOW(); check_signals(0,0,0); @@ -456,7 +456,7 @@ static void file_write(INT32 args) { int fd=FD; THREADS_ALLOW(); - i=write(fd, str->str + written, str->len - written); + i=fd_write(fd, str->str + written, str->len - written); THREADS_DISALLOW(); #ifdef _REENTRANT @@ -1268,7 +1268,7 @@ static void file_dup2(INT32 args) if(fd < 0) error("File given to dup2 not open.\n"); - if(dup2(FD,fd) < 0) + if(fd_dup2(FD,fd) < 0) { ERRNO=errno; pop_n_elems(args); diff --git a/src/modules/files/socket.c b/src/modules/files/socket.c index ce609254b9d00d2fbe2086433713bc8f6a317e61..a497d97962b8dd86647d142e1d308c90f93cb596 100644 --- a/src/modules/files/socket.c +++ b/src/modules/files/socket.c @@ -223,7 +223,7 @@ static void port_bind(INT32 args) addr.sin_family = AF_INET; THREADS_ALLOW(); - tmp=fd_bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0 || listen(fd, 16384) < 0; + tmp=fd_bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0 || fd_listen(fd, 16384) < 0; THREADS_DISALLOW(); if(tmp) diff --git a/src/modules/files/testsuite.in b/src/modules/files/testsuite.in index 379e04d2da0377195f9d6399bfbb9b33355e1514..03dec921ca44f185c3ff91d51a13131e7da30470 100644 --- a/src/modules/files/testsuite.in +++ b/src/modules/files/testsuite.in @@ -19,7 +19,7 @@ test_true(rm("conftest")) test_eq(file_stat("conftest"),0) // - file->write -test_any(int e; object o=clone(Stdio.File); if(!o->open("conftest","wct")) return -1; e=o->write("sune"); if(!o->close()) return -1; return e,4) +test_any(int e; object o=clone(Stdio.File); if(!o->open("conftest","wct")) return -3; e=o->write("sune"); if(!o->close()) return -2; return e,4) // - file->read test_any(string s; object o=clone(Stdio.File); if(!o->open("conftest","r")) return -1; s=o->read(4); if(!o->close()) return -1; return s,"sune") @@ -35,7 +35,7 @@ test_any(string s; object o=clone(Stdio.File); if(!o->open("conftest","r")) retu test_any(object o=clone(Stdio.File); return o->open("conftest","r") && o->read(4711) && o->tell() == 4711 && o->close(),1) // - file->stat -test_any(object o=clone(Stdio.File); return equal(o->open("conftest","r") && o->stat(), file_stat("conftest")),1) +test_equal([[Stdio.File("conftest","r")->stat()]],[[file_stat("conftest")]]) // - file->errno test_do(clone(Stdio.File,"stdin")->errno()) @@ -69,7 +69,7 @@ test_any([[object o=clone(Stdio.File); o->open("conftest","r"); o=o->dup(); retu est_any([[object o=clone(Stdio.File),o2=clone(Stdio.File); o->open("conftest","r"); o2->assign(o); return o2->read(100)]] ,sprintf("%'+-*'100s","")) // - file->dup2 -test_any([[object o=clone(Stdio.File),o2=clone(Stdio.File); o2->pipe(); o->open("conftest","r"); o->dup2(o2); return o2->read(100)]] ,sprintf("%'+-*'100s","")) +test_any([[object o=clone(Stdio.File),o2=clone(Stdio.File); o2->pipe(); o->open("conftest","r"); o2->dup2(o); return o2->read(100)]] ,sprintf("%'+-*'100s","")) test_eq(Process.popen("echo foo"),"foo\n") diff --git a/src/port.c b/src/port.c index 4c9d28a907071a14ed1a01cf981cfade66383442..317cbe5374b35e3142879feb28d74b6224f2bde9 100644 --- a/src/port.c +++ b/src/port.c @@ -26,14 +26,14 @@ time_t time PROT((time_t *)); void GETTIMEOFDAY(struct timeval *t) { - double t; + double t2; FILETIME tmp; GetSystemTimeAsFileTime(&tmp); - t=tmp.dwHighDateTime * pow(2.0,32) + (double)tmp.dwLowDateTime; - t/=10000000.0; - t+=11644473600.0; - t->tv_sec=floor(t); - t->tv_usec=(t - t->tv_sec)*1000000.0; + t2=tmp.dwHighDateTime * pow(2.0,32.0) + (double)tmp.dwLowDateTime; + t2/=10000000.0; + t2-=11644473600.0; + t->tv_sec=floor(t2); + t->tv_usec=(t2 - t->tv_sec)*1000000.0; } #else diff --git a/src/testsuite.in b/src/testsuite.in index 5fae3d71ab64c55ca6a10c54f4800767b0e01df9..0a35be4b6673de8506584b8aadb09627a346a0a4 100644 --- a/src/testsuite.in +++ b/src/testsuite.in @@ -1,4 +1,4 @@ -test_true([["$Id: testsuite.in,v 1.62 1997/12/03 22:46:18 hubbe Exp $"]]) +test_true([["$Id: testsuite.in,v 1.63 1998/01/03 07:12:11 hubbe Exp $"]]) test_eq(1e1,10.0) test_eq(1E1,10.0) test_eq(1e+1,10.0) @@ -396,20 +396,20 @@ test_eq(foo->i[0],17) test_do(add_constant("foo")); // signum, signame -test_eq(signum("SIGKILL"),9) -test_eq(signum("SIGINT"),2) -test_eq(signame(9),"SIGKILL") -test_eq(signame(2),"SIGINT") +test_true(intp(signum("SIGKILL"))) // kill, signal, getpid test_true(intp(getpid())) -test_do(signal(signum("SIGFPE"),lambda() { add_constant("AFJLLAF",17); })) -test_do(kill(getpid(),signum("SIGFPE"))) -test_do(sleep(2)) -test_eq(AFJLLAF,17) -test_do(add_constant("AFJLLAF")) -test_do(signal(signum("SIGFPE",0))) -test_do(signal(signum("SIGFPE"))) +cond([[all_constants()->kill]], +[[ + test_do(signal(signum("SIGFPE"),lambda() { add_constant("AFJLLAF",17); })) + test_do(kill(getpid(),signum("SIGFPE"))) + test_do(sleep(2)) + test_eq(AFJLLAF,17) + test_do(add_constant("AFJLLAF")) + test_do(signal(signum("SIGFPE",0))) + test_do(signal(signum("SIGFPE"))) +]]) // typeof test_eq(typeof(1),"int") diff --git a/src/threads.c b/src/threads.c index f9d9a8691b9832e5807deac3ae000a7560ccdbf5..6221538f632125e77b9d170618a19675300d81ae 100644 --- a/src/threads.c +++ b/src/threads.c @@ -1,5 +1,5 @@ #include "global.h" -RCSID("$Id: threads.c,v 1.49 1998/01/02 08:18:43 hubbe Exp $"); +RCSID("$Id: threads.c,v 1.50 1998/01/03 07:12:12 hubbe Exp $"); int num_threads = 1; int threads_disabled = 0; @@ -15,6 +15,74 @@ int threads_disabled = 0; #include "program.h" #include "gc.h" +#ifdef SIMULATE_COND_WITH_EVENT +int co_wait(COND_T *c, MUTEX_T *m) +{ + struct cond_t_queue me; + event_init(&me.event); + mt_lock(& c->lock); + + me.next=c->tail; + c->tail=&me; + if(!c->head) c->head=&me; + + mt_unlock(& c->lock); + mt_unlock(m); + event_wait(&me.event); + mt_lock(m); + + event_destroy(& me.event); + /* Cancellation point?? */ + + return 0; +} + +int co_signal(COND_T *c) +{ + struct cond_t_queue *t; + mt_lock(& c->lock); + if(t=c->head) + { + c->head=t->next; + t->next=0; + if(!c->head) c->tail=0; + } + mt_unlock(& c->lock); + if(t) + event_signal(& t->event); + return 0; +} + +int co_broadcast(COND_T *c) +{ + struct cond_t_queue *t,*n; + mt_lock(& c->lock); + n=c->head; + c->head=c->tail=0; + mt_unlock(& c->lock); + + while((t=n)) + { + n=t->next; + event_signal(& t->event); + } + + return 0; +} + +int co_destroy(COND_T *c) +{ + struct cond_t_queue *t; + mt_lock(& c->lock); + n=c->head; + c->head=c->tail=0; + if(t) return EBUSY; + return 0; +} + +#endif + + #define THIS_THREAD ((struct thread_state *)fp->current_storage) struct object *thread_id; diff --git a/src/threads.h b/src/threads.h index a857e23579d143375776423088dc64e5e4b9d0fe..4e3866d7e18b475ef225113adfdcf447d59dd184 100644 --- a/src/threads.h +++ b/src/threads.h @@ -155,21 +155,58 @@ extern struct object *thread_id; #ifdef NT_THREADS #include <process.h> -#define MUTEX_T HANDLE -#define mt_init(X) -#define mt_lock(X) -#define mt_trylock(X) -#define mt_unlock(X) -#define mt_destroy(X) - #define THREAD_T HANDLE #define th_setconcurrency(X) #define th_create(ID,fun,arg) _beginthreadex(NULL, 2*1024*1024, fun, arg, 0, ID) #define th_exit(foo) _endthreadex(foo) -#define th_self() +#define th_self() GetCurrentThread() +#define th_destroy(X) CloseHandle(*(X)) +#define th_yield() Sleep(0) + +#define MUTEX_T HANDLE +#define mt_init(X) (*(X)=CreateMutex(NULL, 0, NULL)) +#define mt_lock(X) WaitForSingleObject(*(X), INFINITE) +#define mt_trylock(X) WaitForSingleObject(*(X), 0) +#define mt_unlock(X) ReleaseMutex(*(X)) +#define mt_destroy(X) CloseHandle(*(X)) + +#define EVENT_T HANDLE +#define event_init(X) (*(X)=CreateEvent(NULL, 1, 0, NULL)) +#define event_signal(X) SetEvent(*(X)) +#define event_destroy(X) CloseHandle(*(X)) +#define event_wait(X) WaitForSingleObject(*(X), INFINITE) #endif + +#if !defined(COND_T) && defined(EVENT_T) && defined(MUTEX_T) + +#define SIMULATE_COND_WITH_EVENT + +struct cond_t_queue +{ + struct cond_t_queue *next; + EVENT_T event; +}; + +struct cond_t_s +{ + MUTEX_T lock; + struct cond_t_queue *head, *tail +} COND_T; + +#define COND_T struct cond_t_s + +#define co_init(X) mt_init(& (X)->lock) + +int co_wait(COND_T *c, MUTEX_T *m); +int co_signal(COND_T *c); +int co_broadcast(COND_T *c); +int co_destroy(COND_T *c); + +#endif + + extern MUTEX_T interpreter_lock; @@ -195,6 +232,14 @@ struct thread_state { struct object * thread_id; }; +#ifndef th_destroy +#define th_destroy(X) +#endif + +#ifndef th_yield +#define th_yield() +#endif + /* Define to get a debug-trace of some of the threads operations. */ /* #define VERBOSE_THREADS_DEBUG */