diff --git a/M2/Macaulay2/d/actors2.dd b/M2/Macaulay2/d/actors2.dd index d9b19fc98cd..33232c68d11 100644 --- a/M2/Macaulay2/d/actors2.dd +++ b/M2/Macaulay2/d/actors2.dd @@ -4,6 +4,8 @@ use evaluate; use struct; use sets; +header "#include "; -- for NI_MAXHOST and NI_MAXSERV + dbmfirst(e:Expr):Expr := ( when e is f:Database do dbmfirst(f) @@ -398,99 +400,148 @@ export setStdIO (f:file):void := ( stdIO = f; setGlobalVariable(stdioS, Ex export setStdError(f:file):void := ( stdError = f; setGlobalVariable(stderrS, Expr(stdError))); openfilesfun(e:Expr):Expr := ( - n := 0; - ff := openfiles; - while true do ( - when ff - is null do break - is f:FileCell do (n=n+1; ff=f.next;)); - v := new Sequence len n do ( - ff = openfiles; - while true do ( - when ff - is null do break - is f:FileCell do (provide f.file; ff=f.next;)); - ); - list(v)); + when e + is a:Sequence do ( + -- typical value: openFiles, List + if length(a) == 0 then ( + n := 0; + ff := openfiles; + while true do ( + when ff + is null do break + is f:FileCell do (n=n+1; ff=f.next;)); + v := new Sequence len n do ( + ff = openfiles; + while true do ( + when ff + is null do break + is f:FileCell do (provide f.file; ff=f.next;)); + ); + list(v)) + else WrongNumArgs(0)) + else WrongNumArgs(0)); setupfun("openFiles",openfilesfun); openIn(filename:Expr):Expr := ( when filename + -- # typical value: openIn, File, File is f:file do ( when openIn(f) is g:file do Expr(g) is m:errmsg do buildErrorPacket(m.message)) + -- # typical value: openIn, String, File is f:stringCell do ( when openIn(f.v) is g:file do Expr(g) is m:errmsg do buildErrorPacket(m.message)) - is Error do filename - else WrongArgString()); + else WrongArg("a file or string")); setupfun("openIn",openIn); openOut(filename:Expr):Expr := ( when filename + -- # typical value: openOut, File, File is f:file do ( when openOut(f) is g:file do Expr(g) is m:errmsg do buildErrorPacket(m.message)) + -- # typical value: openOut, String, File is f:stringCell do ( when openOut(f.v) is g:file do Expr(g) is m:errmsg do buildErrorPacket(m.message)) - is Error do filename else WrongArgString()); setupfun("openOut",openOut); openOutAppend(filename:Expr):Expr := ( when filename + -- # typical value: openOutAppend, File, File + is f:file do ( + when openOut(f) + is g:file do Expr(g) + is m:errmsg do buildErrorPacket(m.message)) + -- # typical value: openOutAppend, String, File is f:stringCell do ( when openOutAppend(f.v) is g:file do Expr(g) is m:errmsg do buildErrorPacket(m.message)) - is Error do filename else WrongArgString()); setupfun("openOutAppend",openOutAppend); openInOut(filename:Expr):Expr := ( when filename + -- # typical value: openInOut, File, File is f:file do ( when openInOut(f) is g:file do Expr(g) is m:errmsg do buildErrorPacket(m.message)) + -- # typical value: openInOut, String, File is f:stringCell do ( when openInOut(f.v) is g:file do Expr(g) is m:errmsg do buildErrorPacket(m.message)) - is Error do filename else WrongArgString()); setupfun("openInOut",openInOut); openListener(filename:Expr):Expr := ( when filename + -- # typical value: openListener, String, File is f:stringCell do ( when openListener(f.v) is g:file do Expr(g) is m:errmsg do buildErrorPacket(m.message)) - is Error do filename else WrongArgString()); setupfun("openListener",openListener); isOpen(e:Expr):Expr := ( when e + -- # typical value: isOpen, File, Boolean is f:file do toExpr(f.listener || f.input || f.output) + -- # typical value: isOpen, Database, Boolean is x:Database do toExpr(x.isopen) else WrongArg("a file or database")); setupfun("isOpen",isOpen); isInputFile(e:Expr):Expr := ( when e + -- # typical value: isInputFile, File, Boolean is f:file do toExpr(f.input) else False); setupfun("isInputFile",isInputFile); isOutputFile(e:Expr):Expr := ( when e + -- # typical value: isOutputFile, File, Boolean is f:file do toExpr(f.output) else False); setupfun("isOutputFile",isOutputFile); isListener(e:Expr):Expr := ( when e + -- # typical value: isListener, File, Boolean is f:file do toExpr(f.listener) else False); setupfun("isListener",isListener); +getPeerName(e:Expr):Expr := ( + when e + -- # typical value: getPeerName, File, Sequence + is f:file do ( + if f.input then ( + host := new string len Ccode(int, "NI_MAXHOST") do provide ' '; + serv := new string len Ccode(int, "NI_MAXSERV") do provide ' '; + r := getpeername(f.infd, host, serv); + if r < 0 then buildErrorPacket( + "can't get peer name: " + netstrerror(r)) + else seq(toExpr(host), toExpr(serv))) + else WrongArg("an input file")) + else WrongArg("a file")); +setupfun("getPeerName", getPeerName); +getSocketName(e:Expr):Expr := ( + when e + -- # typical value: getSocketName, File, Sequence + is f:file do ( + fd := 0; + if f.listener then fd = f.listenerfd + else if f.output then fd = f.outfd + else return WrongArg("a listener or output file"); + host := new string len Ccode(int, "NI_MAXHOST") do provide ' '; + serv := new string len Ccode(int, "NI_MAXSERV") do provide ' '; + r := getsockname(fd, host, serv); + if r < 0 then buildErrorPacket( + "can't get socket name: " + netstrerror(r)) + else seq(toExpr(host), toExpr(serv))) + else WrongArg("a file")); +setupfun("getSocketName", getSocketName); header " #if WITH_MYSQL diff --git a/M2/Macaulay2/d/expr.d b/M2/Macaulay2/d/expr.d index 7958fd5a315..1f5cc5e7de5 100644 --- a/M2/Macaulay2/d/expr.d +++ b/M2/Macaulay2/d/expr.d @@ -360,7 +360,6 @@ export pseudocodeClosureClass := newtypeof(pseudocodeClass); --Error Handling export buildErrorPacket(message:string):Expr := Expr(Error(dummyPosition,message,nullE,false,dummyFrame)); -export buildErrorPacketErrno(msg:string,errnum:int):Expr := buildErrorPacket( msg + ": " + strerror(errnum) ); export quoteit(name:string):string := "'" + name + "'"; export NotYet(desc:string):Expr := buildErrorPacket(desc + " not implemented yet"); diff --git a/M2/Macaulay2/d/hashtables.dd b/M2/Macaulay2/d/hashtables.dd index 316b9df4b91..be753061074 100644 --- a/M2/Macaulay2/d/hashtables.dd +++ b/M2/Macaulay2/d/hashtables.dd @@ -416,7 +416,7 @@ installIt(numtypes:int,assgnmt:bool,h:HashTable,key:Expr,value:Expr):Expr := ( else buildErrorPacket(messx)); ----------------------------------------------------------------------------- -- nullary methods -export NullaryMethods := newHashTableWithHash(mutableHashTableClass,nothingClass); +export NullaryMethods := newHashTableWithHash(typeClass,nothingClass); setupconst("nullaryMethods",Expr(NullaryMethods)); export lookup(e:Expr):Expr := ( r := lookup1(NullaryMethods,Expr(Sequence(e))); diff --git a/M2/Macaulay2/d/scclib.c b/M2/Macaulay2/d/scclib.c index 6ea015b5cf9..1550d67ecce 100644 --- a/M2/Macaulay2/d/scclib.c +++ b/M2/Macaulay2/d/scclib.c @@ -219,19 +219,25 @@ int system_strnumcmp(M2_string s,M2_string t) { } int fix_status(int status) { - /* We can't handle status codes bigger than 127 if the shell intervenes. */ - return - status == ERROR ? ERROR : - WIFSIGNALED(status) ? /* whether the process died due to a signal */ - WTERMSIG(status) + (WCOREDUMP(status) ? 128 : 0) : /* signal number n, plus 128 if core was dumped */ - WIFEXITED(status) ? /* whether the process exited */ - ( - ((WEXITSTATUS(status) & 0x80) != 0) ? /* whether /bin/sh indicates a signal in a command */ - (WEXITSTATUS(status) & 0x7f) : /* the signal number */ - (WEXITSTATUS(status) << 8) /* status code times 256 */ - ) : - -2; /* still running (or stopped) */ - } + /* We can't handle status codes bigger than 127 if the shell intervenes. */ + if (status == ERROR) + return ERROR; + else if (WIFSIGNALED(status)) { /* whether the process died due to a signal */ +#ifdef WCOREDUMP + return WTERMSIG(status) + (WCOREDUMP(status) ? 128 : 0); /* signal number n, plus 128 if core was dumped */ +#else + return WTERMSIG(status); +#endif + } + else if (WIFEXITED(status)) { /* whether the process exited */ + if ((WEXITSTATUS(status) & 0x80) != 0) /* whether /bin/sh indicates a signal in a command */ + return WEXITSTATUS(status) & 0x7f; /* the signal number */ + else + return WEXITSTATUS(status) << 8; /* status code times 256 */ + } + else + return -2; /* still running (or stopped) */ +} M2_arrayint system_waitNoHang(M2_arrayint pids) { @@ -240,13 +246,17 @@ M2_arrayint system_waitNoHang(M2_arrayint pids) M2_arrayint z = (M2_arrayint)getmem_atomic(sizeofarray(z,n)); z->len = n; for (int i=0; iarray[i] = - ret == ERROR ? -1 : fix_status(status); - #else - z->array[i] = -1; /* not implemented */ - #endif + int status, ret; + + status = 0; + ret = waitpid(pid[i], &status, WNOHANG); + + if (ret == 0) /* still running */ + z->array[i] = -2; + else if (ret == ERROR) + z->array[i] = ERROR; + else + z->array[i] = fix_status(status); } return z; } @@ -612,17 +622,6 @@ M2_string system_readfile(int fd) { return s; } -static const char *hostname_error_message; - -#if defined(HAVE_GETADDRINFO) && GETADDRINFO_WORKS -static int set_addrinfo(struct addrinfo **addr, struct addrinfo *hints, char *hostname, char *service) { - int ret; - ret = getaddrinfo(hostname, service, hints /* thanks to Dan Roozemond for pointing out this was NULL before, causing problems */, addr); - hostname_error_message = ret != 0 ? gai_strerror(ret) : NULL; - return ret; -} -#endif - #ifndef HAVE_HSTRERROR const char *hstrerror(int herrno) { switch(herrno) { @@ -636,81 +635,17 @@ const char *hstrerror(int herrno) { } #endif -#if !(defined(HAVE_GETADDRINFO) && GETADDRINFO_WORKS) -int host_address(name) -char *name; -{ -#ifdef HAVE_SOCKET - if ('0' <= name[0] && name[0] <= '9') { - int s; - s = inet_addr(name); /* this function is obsolete, replaced by inet_aton(); we use it only if getaddrinfo is not available */ - if (s == ERROR) { - hostname_error_message = "IP address translation failed"; - return ERROR; - } - return s; - } - else { - struct hostent *t; - /* FIXME - if (SETJMP(interrupt_jump)) { - interrupt_jump_set = FALSE; - return ERROR; - } - else interrupt_jump_set = TRUE; */ - t = gethostbyname(name); /* this function is obsolete because it doesn't handle IPv6; we use it only if getaddrinfo is not available */ - // interrupt_jump_set = FALSE; - if (t == NULL) { - hostname_error_message = hstrerror(h_errno); - return ERROR; - } - else { - return *(int *)t->h_addr; - } - } -#else - return ERROR; -#endif - } - -int serv_address(name) -char *name; -{ -#ifdef HAVE_SOCKET - if ('0' <= name[0] && name[0] <= '9') { - return htons(atoi(name)); - } - else { - struct servent *t = getservbyname(name,"tcp"); - if (t == NULL) { - errno = ENXIO; - return ERROR; - } - else { - return t->s_port; - } - } -#else - return ERROR; -#endif - } -#endif - int system_acceptBlocking(int so) { -#ifdef HAVE_ACCEPT struct sockaddr_in addr; socklen_t addrlen = sizeof addr; #ifdef HAVE_FCNTL fcntl(so,F_SETFL,0); #endif return accept(so,(struct sockaddr*)&addr,&addrlen); -#else - return ERROR; -#endif } int system_acceptNonblocking(int so) { -#if defined(HAVE_SOCKET) && defined(HAVE_FCNTL) +#if defined(HAVE_FCNTL) struct sockaddr_in addr; socklen_t addrlen = sizeof addr; int sd; @@ -722,38 +657,67 @@ int system_acceptNonblocking(int so) { #endif } +/* openlistener and opensocket might encounter errors in getaddrinfo, which + doesn't use errno, or in various other functions that do. + To keep these straight, we return the following: + + * ERROR (#defined as -1 in types.h) when errno is set so we know when + to call strerror(errno) + + * r + ERROR when getaddrinfo raises an error (r = getaddrinfo ret value) + so we can recover r before calling gai_strerror by subtracting ERROR + + The following function determines the error message: +*/ + +M2_string system_netstrerror(int errcode) { + if (errcode == ERROR || errcode - ERROR == EAI_SYSTEM) + return M2_tostring(strerror(errno)); + else + return M2_tostring(gai_strerror(errcode - ERROR)); +} + #define INCOMING_QUEUE_LEN 10 int openlistener(char *interface0, char *service) { -#ifdef HAVE_SOCKET -#if defined(HAVE_GETADDRINFO) && GETADDRINFO_WORKS - struct addrinfo *addr = NULL; - static struct addrinfo hints; /* static so all parts get initialized to zero */ - int so; - hints.ai_family = PF_UNSPEC; + struct addrinfo *addr, *p, hints; + int so, r; + + addr = NULL; + p = NULL; + memset(&hints, 0, sizeof(hints)); + + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; - if (0 != set_addrinfo(&addr,&hints,interface0,service)) return ERROR; - so = socket(addr->ai_family,SOCK_STREAM,0); - if (ERROR == so) { freeaddrinfo(addr); return ERROR; } - if (ERROR == bind(so,addr->ai_addr,addr->ai_addrlen) || ERROR == listen(so, INCOMING_QUEUE_LEN)) { freeaddrinfo(addr); close(so); return ERROR; } - freeaddrinfo(addr); - return so; -#else - int sa = serv_address(service); - int so = socket(AF_INET,SOCK_STREAM,0); - struct sockaddr_in addr; - addr.sin_family = PF_INET; - addr.sin_port = sa; - addr.sin_addr.s_addr = INADDR_ANY; - if (ERROR == so || - ERROR == sa || - ERROR == bind(so,(struct sockaddr*)&addr,sizeof addr) || - ERROR == listen(so, INCOMING_QUEUE_LEN)) { close(so); return ERROR; } + r = getaddrinfo(interface0, service, &hints, &addr); + if (r != 0) + return r + ERROR; /* see note above system_netstrerror */ + + for (p = addr; p != NULL; p = p->ai_next) { + so = socket(p->ai_family, p->ai_socktype, p->ai_protocol); + if (so == ERROR) + continue; + + if (bind(so, p->ai_addr, p->ai_addrlen) == ERROR) { + close(so); + continue; + } + + break; + } + + freeaddrinfo(addr); + + if (p == NULL) + return ERROR; + + if (listen(so, INCOMING_QUEUE_LEN) == ERROR) { + close(so); + return ERROR; + } + return so; -#endif -#else - return ERROR; -#endif } int opensocket(char *host, char *service) { @@ -763,42 +727,40 @@ int opensocket(char *host, char *service) { return ERROR; } else { interrupt_jump_set = TRUE; } */ -#ifdef HAVE_SOCKET -#if defined(HAVE_GETADDRINFO) && GETADDRINFO_WORKS - struct addrinfo *addr; - int so; - if (0 != set_addrinfo(&addr,NULL,host,service)) return ERROR; - so = socket(addr->ai_family,SOCK_STREAM,0); - if (ERROR == so) { freeaddrinfo(addr); return ERROR; } - if (ERROR == connect(so,addr->ai_addr,addr->ai_addrlen)) { freeaddrinfo(addr); close(so); return ERROR; } + struct addrinfo *addr, *p, hints; + int so, r; + + addr = NULL; + p = NULL; + memset(&hints, 0, sizeof(hints)); + + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + r = getaddrinfo(host, service, &hints, &addr); + if (r != 0) + return r + ERROR; /* see note above system_netstrerror */ + + for (p = addr; p != NULL; p = p->ai_next) { + so = socket(p->ai_family, p->ai_socktype, p->ai_protocol); + if (so == ERROR) + continue; + + if (connect(so, p->ai_addr, p->ai_addrlen) == ERROR) { + close(so); + continue; + } + + break; + } + + // interrupt_jump_set = FALSE; freeaddrinfo(addr); + + if (p == NULL) + return ERROR; + return so; -#else - int sd = socket(AF_INET,SOCK_STREAM,0); - struct sockaddr_in addr; - int sa = serv_address(service); - if (sa == ERROR) { - /* strange but true, some systems don't list the common services: - u24% uname -a - SunOS u24.math.uiuc.edu 5.8 Generic_117350-34 sun4u sparc - u24% grep http /etc/services - u24% - */ - if (0 == strcmp(service,"http")) sa = 80; - else if (0 == strcmp(service,"https")) sa = 443; - } - addr.sin_family = PF_INET; - addr.sin_port = sa; - addr.sin_addr.s_addr = host_address(host); - if (ERROR == addr.sin_addr.s_addr || - ERROR == sa || - ERROR == connect(sd,(struct sockaddr *)&addr,sizeof(addr))) { close(sd); return ERROR; } - return sd; -#endif -#else - return ERROR; -#endif } int system_opensocket(M2_string host,M2_string serv) { @@ -819,6 +781,46 @@ int system_openlistener(M2_string interface0,M2_string serv) { return sd; } +int getpeerorsockname(int sockfd, M2_string host, M2_string serv, int peer) { + struct sockaddr addr; + socklen_t addrlen; + int i, r; + char hostbuf[NI_MAXHOST], servbuf[NI_MAXSERV]; + + addrlen = sizeof addr; + if (peer) + r = getpeername(sockfd, &addr, &addrlen); + else + r = getsockname(sockfd, &addr, &addrlen); + + if (r == ERROR) + return ERROR; + + r = getnameinfo(&addr, addrlen, hostbuf, sizeof hostbuf, + servbuf, sizeof servbuf, 0); + if (r != 0) + return r + ERROR; /* see note above system_netstrerror */ + + for (i = 0; hostbuf[i] != '\0'; i++) {} + host->len = i; + + for (i = 0; servbuf[i] != '\0'; i++) {} + serv->len = i; + + memcpy(host->array, hostbuf, host->len); + memcpy(serv->array, servbuf, serv->len); + + return 0; +} + +int system_getpeername(int sockfd, M2_string host, M2_string serv) { + return getpeerorsockname(sockfd, host, serv, 1); +} + +int system_getsockname(int sockfd, M2_string host, M2_string serv) { + return getpeerorsockname(sockfd, host, serv, 0); +} + int system_errno(void) { return #ifdef HAVE_HERROR @@ -828,11 +830,6 @@ int system_errno(void) { } char const *system_strerror(void) { - if (hostname_error_message) { - char const *msg = hostname_error_message; - hostname_error_message = NULL; - return msg; - } if (errno > 0) { char const *msg = strerror(errno); errno = 0; diff --git a/M2/Macaulay2/d/stdio.d b/M2/Macaulay2/d/stdio.d index 98c96422053..59fb2a7b6ee 100644 --- a/M2/Macaulay2/d/stdio.d +++ b/M2/Macaulay2/d/stdio.d @@ -196,6 +196,7 @@ rmfile(o:file):void := ( ))); addfile(stdIO); addfile(stdError); + opensocket(filename:string,input:bool,output:bool,listener:bool):(file or errmsg) := ( if readonlyfiles then return (file or errmsg)(errmsg("--read-only-files: opening a socket not permitted")); host0 := substr(filename,1); @@ -209,7 +210,9 @@ opensocket(filename:string,input:bool,output:bool,listener:bool):(file or errmsg sd := NOFD; if length(host0) == 0 || listener then ( so = openlistener(host0,serv); - if so == ERROR then return (file or errmsg)(errmsg("can't open listener : "+syserrmsg())); + if so < 0 + then return (file or errmsg)( + errmsg("can't open listener: " + netstrerror(so))); if input || output then ( sd = acceptBlocking(so); if sd == ERROR then ( @@ -220,8 +223,9 @@ opensocket(filename:string,input:bool,output:bool,listener:bool):(file or errmsg ) else ( sd = opensocket(host0,serv); - if sd == ERROR then return (file or errmsg)(errmsg("can't open socket : "+syserrmsg())); - ); + if sd < 0 + then return (file or errmsg)( + errmsg("can't open socket: " + netstrerror(sd)))); (file or errmsg)(addfile(newFile(filename, 0, false, "", listener, so, NOFD, if listener then 0 else 1, @@ -348,15 +352,22 @@ export openOut(filename:string):(file or errmsg) := ( true, fd, 0 != isatty(fd), newbuffer(), 0, 0, false,dummyNetList,0,-1,false,0))))); export openOutAppend(filename:string):(file or errmsg) := ( if readonlyfiles then return (file or errmsg)(errmsg("--read-only-files: opening an output file not permitted")); - filename = expandFileName(filename); - fd := openoutappend(filename); - if fd == ERROR - then (file or errmsg)(errmsg(syscallErrorMessage("opening output (append) file \""+filename+"\""))) - else (file or errmsg)(addfile(newFile(filename, 0, - false, "", - false, NOFD,NOFD,0, - false, NOFD, false, "", 0, 0, false,false,noprompt,noprompt,false,true,false,0, - true, fd, 0 != isatty(fd), newbuffer(), 0, 0, false,dummyNetList,0,-1,false,0)))); + if filename === "-" + then (file or errmsg)(stdIO) + else if length(filename) > 0 && filename . 0 == '$' + then opensocket(filename,false,true,false) + else if length(filename) > 0 && filename . 0 == '!' + then openpipe(filename,false,true) + else ( + filename = expandFileName(filename); + fd := openoutappend(filename); + if fd == ERROR + then (file or errmsg)(errmsg(syscallErrorMessage("opening output (append) file \""+filename+"\""))) + else (file or errmsg)(addfile(newFile(filename, 0, + false, "", + false, NOFD,NOFD,0, + false, NOFD, false, "", 0, 0, false,false,noprompt,noprompt,false,true,false,0, + true, fd, 0 != isatty(fd), newbuffer(), 0, 0, false,dummyNetList,0,-1,false,0))))); export openInOut(filename:string):(file or errmsg) := ( if readonlyfiles then return (file or errmsg)(errmsg("--read-only-files: opening an output file not permitted")); if filename === "-" diff --git a/M2/Macaulay2/d/system.d b/M2/Macaulay2/d/system.d index 04e19ac57c2..bc725d7470e 100644 --- a/M2/Macaulay2/d/system.d +++ b/M2/Macaulay2/d/system.d @@ -105,11 +105,12 @@ import openout(filename:string):int; import openoutappend(filename:string):int; import opensocket(host:string,serv:string):int; import openlistener(interface:string,serv:string):int; +import netstrerror(errcode:int):string; import acceptBlocking(sd:int):int; import acceptNonblocking(sd:int):int; +import getpeername(sockd:int,host:string,serv:string):int; +import getsockname(sockd:int,host:string,serv:string):int; import syserrmsg():string; -- uses errno -import strerror():constcharstar; -- uses errno -export strerror(errnum:int):string := tostring(Ccode(constcharstar,"strerror(",errnum,")")); import atend(f:function():void):void; import run(command:string):int; export pipe(fildes:array(int)):int := Ccode(returns," @@ -129,13 +130,9 @@ import strcmp(s:string,t:string):int; import strnumcmp(s:string,t:string):int; import randomint():int; export wait(pid:int):int := Ccode(returns, " - #ifdef HAVE_WAITPID int status; if (waitpid(pid,&status,0) == -1) return -1; return status; - #else - return -1; - #endif "); import waitNoHang(pid:array(int)):array(int); import select(s:array(int)):array(int); diff --git a/M2/Macaulay2/d/tokens.d b/M2/Macaulay2/d/tokens.d index 15d661261f8..c100c8c90f9 100644 --- a/M2/Macaulay2/d/tokens.d +++ b/M2/Macaulay2/d/tokens.d @@ -52,9 +52,6 @@ export unwindMessage := "unhandled unwind command"; export interruptMessage := "interrupted"; export alarmMessage := "alarm occurred"; export steppingMessage := "--stepping limit reached"; ---export buildErrorPacket(message:string):Expr := Expr(Error(dummyPosition,message,nullE,false,dummyFrame)); ---export buildErrorPacket(pos:Position,message:string):Expr := Expr(Error(pos,message,nullE,false,dummyFrame)); ---export buildErrorPacketErrno(msg:string,errnum:int):Expr := buildErrorPacket( msg + ": " + strerror(errnum) ); export handleInterrupts := true; (threadLocal export stopIfError := true) = false; (threadLocal export debuggingMode := false) = true; diff --git a/M2/Macaulay2/d/types.h b/M2/Macaulay2/d/types.h index 2eb7842e72b..4a72ea4f7d3 100644 --- a/M2/Macaulay2/d/types.h +++ b/M2/Macaulay2/d/types.h @@ -124,9 +124,6 @@ struct JumpCell #ifdef HAVE_NETINET_IN_H #include /* needed for struct sockaddr_in */ #endif -#ifdef HAVE_ARPA_INET_H -#include /* needed for inet_addr() */ -#endif #ifdef HAVE_IO_H #include diff --git a/M2/Macaulay2/m2/exports.m2 b/M2/Macaulay2/m2/exports.m2 index 5123230ca10..dd46954f7f0 100644 --- a/M2/Macaulay2/m2/exports.m2 +++ b/M2/Macaulay2/m2/exports.m2 @@ -731,7 +731,9 @@ export { "getIOThreadMode", "getNetFile", "getNonUnit", + "getPeerName", "getPrimeWithRootOfUnity", + "getSocketName", "getSymbol", "getWWW", "getc", diff --git a/M2/Macaulay2/m2/typicalvalues.m2 b/M2/Macaulay2/m2/typicalvalues.m2 index 010a8bfa963..c68225abbe4 100644 --- a/M2/Macaulay2/m2/typicalvalues.m2 +++ b/M2/Macaulay2/m2/typicalvalues.m2 @@ -31,17 +31,7 @@ fileMode(ZZ,File) := fileMode fileMode(ZZ,String) := fileMode get File := get String := String => get getc File := String => getc -isInputFile(File) := Boolean => isInputFile -isListener(File) := Boolean => isListener -isOpen(Database) := Boolean => isOpen -isOpen(File) := Boolean => isOpen -isOutputFile(File) := Boolean => isOutputFile linkFile(String,String) := Nothing => linkFile -openIn String := File => openIn -openInOut String := openInOut File := File => openInOut -openListener String := File => openListener -openOut String := File => openOut -openOutAppend String := File => openOutAppend kill File := Nothing => kill kill ZZ := Nothing => kill read File := String => read @@ -78,7 +68,9 @@ chk := (type,key) -> if type#?key then ( << " " << code type#key << endl; error("method already installed: ",toString type," # ",toString key)) - +typval2f -*(Function,Type)*- := (f,Z) -> ( + chk(nullaryMethods, 1:f); + installMethod(f, Z => dummy)) typval3f-*(Function,Type,Type)*- := (f,X,Z) -> ( msg := toString f | "(" | toString X | ") => " | toString Z; chk(X, f); @@ -135,7 +127,10 @@ redefs := hashTable apply({acos, agm, asin, atan, atan2, Beta, cos, cosh, cot, c variants := new MutableHashTable; typval = x -> ( - if #x == 3 then ( + if #x == 2 then ( + if instance(x#0, Function) then typval2f x + else error "typval: expected a function") + else if #x == 3 then ( if instance(x#0,Function) then typval3f x else if instance(x#0,Keyword) then typval3k x else error "typval: expected keyword or function" @@ -146,7 +141,7 @@ typval = x -> ( else error "typval: expected keyword or function" ) else if #x == 5 then typval5f x - else error "typval: expected 3, 4, or 5 arguments"; + else error "typval: expected 2, 3, 4, or 5 arguments"; if redefs#?(x#0) then ( f' := x#0; f := redefs#f'; diff --git a/M2/cmake/configure.cmake b/M2/cmake/configure.cmake index 30bc3708fad..6cb912953ea 100644 --- a/M2/cmake/configure.cmake +++ b/M2/cmake/configure.cmake @@ -283,7 +283,6 @@ include(CheckIncludeFiles) # TODO: are all still relevant? # HAVE_SCSCP is used in version.dd: https://www.openmath.org/standard/scscp/ check_include_files("stdlib.h;stdarg.h;string.h;float.h" STDC_HEADERS) -check_include_files(arpa/inet.h HAVE_ARPA_INET_H) check_include_files(assert.h HAVE_ASSERT_H) check_include_files(dlfcn.h HAVE_DLFCN_H) check_include_files(execinfo.h HAVE_EXECINFO_H) @@ -315,53 +314,29 @@ check_include_files(unistd.h HAVE_UNISTD_H) # TODO: clear out d/types.h include(CheckFunctionExists) -# TODO: can't getaddrinfo check_function_exists(herror HAVE_HERROR) -check_function_exists(error HAVE_ERROR) -check_function_exists(clock_gettime HAVE_CLOCK_GETTIME) -check_function_exists(getaddrinfo HAVE_GETADDRINFO) check_function_exists(hstrerror HAVE_HSTRERROR) -check_function_exists(sync HAVE_SYNC) check_function_exists(getpgrp HAVE_GETPGRP) check_function_exists(setpgid HAVE_SETPGID) check_function_exists(fchmod HAVE_FCHMOD) check_function_exists(pipe HAVE_PIPE) -check_function_exists(waitpid HAVE_WAITPID) check_function_exists(setrlimit HAVE_SETRLIMIT) check_function_exists(alarm HAVE_ALARM) check_function_exists(fork HAVE_FORK) check_function_exists(sigprocmask HAVE_SIGPROCMASK) check_function_exists(kill HAVE_KILL) check_function_exists(sigaction HAVE_SIGACTION) -check_function_exists(wait4 HAVE_WAIT4) check_function_exists(readlink HAVE_READLINK) check_function_exists(lstat HAVE_LSTAT) check_function_exists(realpath HAVE_REALPATH) -check_function_exists(mkdir HAVE_MKDIR) check_function_exists(link HAVE_LINK) check_function_exists(symlink HAVE_SYMLINK) -check_function_exists(socket HAVE_SOCKET) -check_function_exists(accept HAVE_ACCEPT) check_function_exists(fcntl HAVE_FCNTL) -check_function_exists(personality HAVE_PERSONALITY) -check_function_exists(ioctl HAVE_IOCTL) include(CheckSymbolExists) include(CheckCSourceCompiles) include(CheckCXXSourceCompiles) -# TODO: is this necessary? -# whether getaddrinfo can handle numeric service (port) numbers -check_c_source_compiles([[ - #include - #ifdef HAVE_SYS_SOCKET_H - #include - #endif - #ifdef HAVE_NETDB_H - #include - #endif - int main(){struct addrinfo *addr;return 0 != getaddrinfo("1.2.3.4", "80", 0, &addr) ? 99 : 0;}]] GETADDRINFO_WORKS) - ############################################################################### # this is an alternative for AC_FUNC_ALLOCA() diff --git a/M2/configure.ac b/M2/configure.ac index bd5fe56e472..7488287a371 100644 --- a/M2/configure.ac +++ b/M2/configure.ac @@ -353,7 +353,7 @@ AC_SUBST(SIZEOF_INT_P,$ac_cv_sizeof_int_p) AC_CHECK_SIZEOF([long]) AC_SUBST(SIZEOF_LONG,$ac_cv_sizeof_long) -AC_CHECK_HEADERS(sys/ioctl.h termios.h sys/mman.h sys/socket.h netdb.h netinet/in.h arpa/inet.h sys/time.h time.h sys/wait.h sys/resource.h io.h linux/personality.h stddef.h elf.h execinfo.h syscall.h math.h pthread.h assert.h alloca.h malloc.h dlfcn.h) +AC_CHECK_HEADERS(sys/ioctl.h termios.h sys/mman.h sys/socket.h netdb.h netinet/in.h sys/time.h time.h sys/wait.h sys/resource.h io.h linux/personality.h stddef.h elf.h execinfo.h syscall.h math.h pthread.h assert.h alloca.h malloc.h dlfcn.h) AC_CHECK_HEADERS(winsock2.h) dnl used with ws2_32.dll under mingw64 dnl winsock2.h should be included before including windows.h dnl pthread.h includes windows.h @@ -370,9 +370,9 @@ AC_SEARCH_LIBS(hstrerror,resolv) AC_SEARCH_LIBS(dlopen,dl) AC_SEARCH_LIBS(gethostbyname,nsl) -AC_CHECK_FUNCS([herror error clock_gettime getaddrinfo hstrerror sync getpgrp setpgid fchmod pipe waitpid setrlimit alarm fork sigprocmask kill longjmp siglongjmp sigaction wait4 readlink lstat realpath mkdir link symlink socket accept fcntl personality ioctl]) - -AC_SUBST(HAVE_PERSONALITY,$ac_cv_func_personality) +AC_CHECK_FUNCS([herror hstrerror getprgp setpgid fchmod pipe setrlimit + fork sigprocmask kill sigaction readlink lstat realpath link + symlink fcntl]) if test $host_os = mingw32 then CPPFLAGS="$CPPFLAGS -D_POSIX" # arrange for SIGPIPE to get defined @@ -1616,28 +1616,6 @@ if nm --help 2>&1 | grep demangle >/dev/null else NM_DEMANGLES=no ; AC_MSG_RESULT(no) fi -AC_LANG(C) -AC_MSG_CHECKING([whether getaddrinfo can handle numeric service (port) numbers]) -AC_RUN_IFELSE([AC_LANG_SOURCE([ - #include - #ifdef HAVE_SYS_SOCKET_H - #include - #endif - #ifdef HAVE_WINSOCK2_H - #include - #endif - #ifdef HAVE_NETDB_H - #include - #endif - int main(void) { - struct addrinfo *addr; - return 0 != getaddrinfo("1.2.3.4", "80", 0, &addr) ? 99 : 0 ; - } - ])], - [AC_DEFINE_UNQUOTED(GETADDRINFO_WORKS,1,[whether getaddrinfo can handle numeric service (port) numbers])] [AC_MSG_RESULT(yes)], - [if test $? = 99 ; then AC_MSG_RESULT(no) ; else AC_MSG_ERROR([test file failed to compile]) ; fi], - [AC_DEFINE_UNQUOTED(GETADDRINFO_WORKS,1,[whether getaddrinfo can handle numeric service (port) numbers])] [AC_MSG_RESULT([probably (cross-compiling, not tested)])]) - AC_SUBST(BUILDLIST) for i in $LIBLIST $PROGLIST do eval t=\$BUILD_$i diff --git a/M2/include/M2/config.h.cmake b/M2/include/M2/config.h.cmake index 8668ca07fee..ab06e1325b5 100644 --- a/M2/include/M2/config.h.cmake +++ b/M2/include/M2/config.h.cmake @@ -47,18 +47,6 @@ /* libffi version */ #define FFI_VERSION "${FFI_VERSION}" -// TODO: only used in Macaulay2/d/scclib.c. Still needed? -/* whether getaddrinfo can handle numeric service (port) numbers */ -#cmakedefine GETADDRINFO_WORKS 1 - -// TODO: only used in Macaulay2/d/scclib.c. Still needed? -/* Define to 1 if you have the `accept' function. */ -#cmakedefine HAVE_ACCEPT 1 - -// TODO: only used in Macaulay2/d/interrupts.d. Still needed? -/* Defined if you have the `alarm' function. */ -#cmakedefine HAVE_ALARM - // TODO: used a few places, what is it for? /* Define to 1 if you have `alloca', as a function or macro. */ #cmakedefine HAVE_ALLOCA 1 @@ -74,10 +62,6 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_ASSERT_H 1 -// TODO: only used in Macaulay2/d/M2lib.c. Still needed? -/* Defined if you have the `clock_gettime' function. */ -#cmakedefine HAVE_CLOCK_GETTIME - /* Defined if you have the header file. */ #cmakedefine HAVE_DLFCN_H @@ -85,10 +69,6 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_ELF_H 1 -// TODO: remove? -/* Define to 1 if you have the `error' function. */ -#cmakedefine HAVE_ERROR 1 - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_EXECINFO_H 1 @@ -105,9 +85,6 @@ /* whether we are linking with the fplll library */ #cmakedefine HAVE_FPLLL 1 -/* Define to 1 if you have the `getaddrinfo' function. */ -#cmakedefine HAVE_GETADDRINFO 1 - /* Define to 1 if you have the `getpgrp' function. */ #cmakedefine HAVE_GETPGRP 1 @@ -123,9 +100,6 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_INTTYPES_H 1 -/* Define to 1 if you have the `ioctl' function. */ -#cmakedefine HAVE_IOCTL 1 - // TODO: used in Macaulay2/d/types.h. Still needed? /* Define to 1 if you have the header file. */ #cmakedefine HAVE_IO_H 1 @@ -143,9 +117,6 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_LINUX_PERSONALITY_H 1 -/* Define to 1 if you have the `longjmp' function. */ -#cmakedefine HAVE_LONGJMP 1 - /* Define to 1 if you have the `lstat' function. */ #cmakedefine HAVE_LSTAT 1 @@ -158,18 +129,12 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_MEMORY_H 1 -/* Define to 1 if you have the `mkdir' function. */ -#cmakedefine HAVE_MKDIR 1 - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_NETDB_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_NETINET_IN_H 1 -/* Define to 1 if you have the `personality' function. */ -#cmakedefine HAVE_PERSONALITY 1 - /* Define to 1 if you have the `pipe' function. */ #cmakedefine HAVE_PIPE 1 @@ -191,15 +156,9 @@ /* Define to 1 if you have the `sigaction' function. */ #cmakedefine HAVE_SIGACTION 1 -/* Define to 1 if you have the `siglongjmp' function. */ -#cmakedefine HAVE_SIGLONGJMP 1 - /* Define to 1 if you have the `sigprocmask' function. */ #cmakedefine HAVE_SIGPROCMASK 1 -/* Define to 1 if you have the `socket' function. */ -#cmakedefine HAVE_SOCKET 1 - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STDDEF_H 1 @@ -218,9 +177,6 @@ /* Define to 1 if you have the `symlink' function. */ #cmakedefine HAVE_SYMLINK 1 -/* Define to 1 if you have the `sync' function. */ -#cmakedefine HAVE_SYNC 1 - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYSCALL_H 1 @@ -260,12 +216,6 @@ /* Defined if you have the header file. */ #cmakedefine HAVE_REGEX_H -/* Define to 1 if you have the `wait4' function. */ -#cmakedefine HAVE_WAIT4 1 - -/* Define to 1 if you have the `waitpid' function. */ -#cmakedefine HAVE_WAITPID 1 - /* issue (flavor) of operating system, if any */ #define ISSUE "${ISSUE}" diff --git a/M2/include/configuration.in b/M2/include/configuration.in index d86ced6c292..e8a5cd216f6 100644 --- a/M2/include/configuration.in +++ b/M2/include/configuration.in @@ -37,7 +37,6 @@ FC=@FC@ FCFLAGS=@FCFLAGS@ FCLIBS=@FCLIBS@ GCC=@GCC@ -HAVE_PERSONALITY=@HAVE_PERSONALITY@ IMPLINST=@IMPLINST@ INSTALL=@INSTALL@ INSTALL_DATA=@INSTALL_DATA@