From 5a7ab60e25b94765c6a6062a12a0781c30f0f364 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net> Date: Sat, 31 Jan 1998 18:08:25 -0800 Subject: [PATCH] Many patches for NT... Rev: NT/tools/cp:1.3 Rev: NT/tools/install:1.3 Rev: NT/tools/lib:1.12 Rev: NT/tools/mkdir:1.3 Rev: NT/tools/rntcc:1.10 Rev: NT/tools/sprsh:1.2 Rev: NT/tools/sprshd:1.6 Rev: src/builtin_functions.c:1.66 Rev: src/error.c:1.12 Rev: src/error.h:1.12 Rev: src/fdlib.c:1.11 Rev: src/fdlib.h:1.8 Rev: src/interpret.c:1.65 Rev: src/modules/files/file.c:1.73 Rev: src/modules/files/socket.c:1.28 Rev: src/pike_memory.c:1.12 Rev: src/program.h:1.31 Rev: src/signal_handler.c:1.28 --- NT/tools/cp | 29 +-- NT/tools/install | 37 ++- NT/tools/lib | 1 + NT/tools/mkdir | 23 +- NT/tools/rntcc | 449 +++++++++++++++++++------------------ NT/tools/sprsh | 37 +-- NT/tools/sprshd | 31 ++- src/builtin_functions.c | 22 +- src/error.c | 4 +- src/error.h | 5 +- src/fdlib.c | 126 +++++++++-- src/fdlib.h | 5 +- src/interpret.c | 20 +- src/modules/files/file.c | 23 +- src/modules/files/socket.c | 5 +- src/pike_memory.c | 1 + src/program.h | 2 +- src/signal_handler.c | 12 +- 18 files changed, 481 insertions(+), 351 deletions(-) diff --git a/NT/tools/cp b/NT/tools/cp index ff2ec26424..554acd66db 100755 --- a/NT/tools/cp +++ b/NT/tools/cp @@ -1,14 +1,15 @@ -#!/bin/sh - -dest=`eval echo '$'$#` - -case "x$dest" in - x[a-zA-Z]:*) - . $NTTOOLS - do_cmd copy `fixpath $*` - exit $? - ;; -esac - -exec /bin/cp "$@" - +#!/usr/local/bin/pike + +inherit "lib.pike"; + +int main(int argc, string *argv) +{ + if(sscanf(argv[-1],"%*[a-zA-Z]:%*s")) + { + argv[0]="copy"; + exit(do_cmd( Array.map(argv,fixpath))); + }else{ + exece("/bin/cp",argv[1..]); + exit(69); + } +} diff --git a/NT/tools/install b/NT/tools/install index cef825764e..c1a4d7f009 100755 --- a/NT/tools/install +++ b/NT/tools/install @@ -1,24 +1,17 @@ -#!/bin/sh +#!/usr/local/bin/pike -dest=`eval echo '$'$#` - - -case "x$dest" in - x[a-zA-Z]:*) - . $NTTOOLS - - if test "x$1" = "x-c" ; then - shift - fi - - if test -f "$1.exe" ; then - set -- "$1.exe" "$2" - fi - - do_cmd copy `fixpath $*` - exit $? - ;; -esac - -exec /usr/bin/install "$@" +inherit "lib.pike"; +int main(int argc, string *argv) +{ + if(sscanf(argv[-1],"%*[a-zA-Z]:%*s")) + { + argv[0]="copy"; + if(argv[1]=="-c") argv=argv[..0]+argv[2..]; + if(file_stat(argv[1]+".exe")) argv[1]+=".exe"; + exit(do_cmd( Array.map(argv,fixpath))); + }else{ + exece("/usr/bin/install",argv[1..]); + exit(69); + } +} diff --git a/NT/tools/lib b/NT/tools/lib index 005d50ef2e..dbd3a51005 100644 --- a/NT/tools/lib +++ b/NT/tools/lib @@ -48,3 +48,4 @@ do_cmd() { echo "DOING $*" >&2 silent_do_cmd "$@" } + diff --git a/NT/tools/mkdir b/NT/tools/mkdir index 01df97c14d..8529a862db 100755 --- a/NT/tools/mkdir +++ b/NT/tools/mkdir @@ -1,12 +1,15 @@ -#!/bin/sh +#!/usr/local/bin/pike +inherit "lib.pike"; -case "x$1" in - x[a-zA-Z]:*) - . $NTTOOLS - do_cmd mkdir `fixpath $1` - exit 0 - ;; -esac - -exec /bin/mkdir "$@" +int main(int argc, string *argv) +{ + if(sscanf(argv[-1],"%*[a-zA-Z]:%*s")) + { + argv[0]="mkdir"; + exit(do_cmd( Array.map(argv,fixpath))); + }else{ + exece("/bin/mkdir",argv[1..]); + exit(69); + } +} diff --git a/NT/tools/rntcc b/NT/tools/rntcc index 0ae5085d57..4e7b7f0850 100755 --- a/NT/tools/rntcc +++ b/NT/tools/rntcc @@ -1,227 +1,230 @@ -#!/bin/sh - -. $NTTOOLS - -OPTS="" -CFLAGS="" -SOURCES="" -OBJECTS="" -OUTPUT= -OPERATION=linking -INCLUDE_PATH= -LDOPTS="OPTION STACK=8m" -LIBRARIES="" -NTCC=wcc386 - -DEBUG=no -OPTIMIZE=no - -check_linker_error() { - ERROR=ok - sed -e 's/\\/\\\\/g' | while read line - do - echo "$line" >&2 - case "x$line" in - *\ W1008:*) - ERROR=failed - ;; - esac - done - - echo $ERROR - exit 0 +#!/usr/local/bin/pike + +inherit "lib.pike"; + +int compile(string *sources, + string dest, + string errorfile, + string *cflags) +{ + int ret; + if(!dest) + { + string tmp=reverse(sources[0]); + sscanf(tmp,"%*s.%s",tmp); + dest=reverse(tmp)+".o"; + } + + sources=Array.map(sources,fixpath); + if(lower_case(sources[0][strlen(sources[0])-3..])==".s") + { + ret=do_cmd(({ "wasm", "-fe"+errorfile, "-fo"+dest,})+ sources ); + }else{ + ret=do_cmd(({ "wcc386" }) + cflags + ({"-fr"+errorfile, "-fo"+dest}) + sources ); + } + return ret; } -while test "$#" != 0; do - case $1 in - -shared) ;; - -E) OPERATION=preprocessing ;; - -c) OPERATION=compiling ;; - -g*) - CFLAGS="$CFLAGS -d2 " - LDOPTS="$LDOPTS DEBUG WATCOM ALL" - DEBUG=yes - ;; -# -O*) ;; - -O) - CFLAGS="$CFLAGS -ox" - OPTIMIZE=yes - ;; - -O2) - CFLAGS="$CFLAGS -otexan" - OPTIMIZE=yes - ;; - *.c | *.s | *.S) SOURCES="$SOURCES $1" ;; - *.o | *.a) OBJECTS="$OBJECTS $1" ;; - -o) OUTPUT="$2" ; shift ;; - - -I*) - if test x$1 = x-I ; then - tmp="$2" - shift - else - tmp=`echo $1 | sed -e 's/^-I//g'` - fi - - case $tmp in - /usr/include/* | /usr/local/include*) - ;; - *) - CFLAGS="$CFLAGS -i`fixpath $tmp`" - ;; - esac - ;; - - -traditional-cpp | -lc | -lm) ;; - - -R | -L) shift ;; - -R* | -L* | -Wl*) ;; - - -W) - CFLAGS="$CFLAGS -w2" - ;; - - -Wall) - CFLAGS="$CFLAGS -wx" - ;; - - -D*) - CFLAGS="$CFLAGS `echo $1 | sed -e 's/^-D/-d/g'`" - ;; - - -U*) - CFLAGS="$CFLAGS `echo $1 | sed -e 's/^-U/-u/g'`" - ;; - - -l*) - tmp=`echo $1 | sed -e 's/^-l//'` - LIBRARIES="$LIBRARIES LIBRARY $tmp" - ;; - - -*) - echo "Unrecognized option $1" - exit 1 - ;; - - *) - SOURCES="$SOURCES $1" - ;; - esac - shift -done - -#if [ x$DEBUG$OPTIMIZE = xyesyes ]; then -# echo Debug and optimization not supported at the same time -# exit 1 -#else -# : -#fi - -rm $OUTPUT 2>/dev/null 1>/dev/null || : - -OLDIFS="$IFS" -IFS=: -set dummy $INCLUDE_PATH -shift -IFS="$OLDIFS" - -IPATH=. -IPATHS=":.:" - -for a in "$@" -do - case $IPATHS in - *:$a:*) ;; - *) - IPATH="$IPATH;`fixpath $a`" - IPATHS="$IPATHS:$a:" - ;; - esac -done - - -ERRORFILE=TMP$$.err -rm $ERRORFILE 2>/dev/null 1>/dev/null || : - -CFLAGS="$CFLAGS -bm -zq -hw -fr$ERRORFILE" - - -compile() { - if [ "x$2" != x ]; then - OFLAGS="$OFLAGS -fo$2" - else - OFLAGS="$OFLAGS -fo`echo $1 | sed -e 's/\.[^.]$//'`.o" - fi - - case $1 in - *.s | *.S) - do_cmd wasm -fe$ERRORFILE $OFLAGS `fixpath $1` - ;; - - *) - do_cmd $NTCC $CFLAGS $OFLAGS `fixpath $1` - ;; - esac +string check_errorfile(string errorfile) +{ + object f=Stdio.File(); + if(f->open(errorfile,"r")) + { + string data; + write(data=f->read()); + f->close(); + data=replace(data,"\r",""); + rm(errorfile); + foreach(data/"\n", string line) + { + if(!strlen(line)) continue; + if(search(line,"Warning")!=-1) continue; + werror("Error in compilation detected. "+line+"\n"); + exit(1); + } + } } -case $OPERATION in - compiling) - compile $SOURCES $OUTPUT - TARGET=$OUTPUT - ;; - - preprocessing) - silent_do_cmd $NTCC -p $CFLAGS `fixpath $SOURCES` - ;; - - linking) - for a in `fixpath $SOURCES` - do - BASE=`echo $a | sed -e 's/\.[^.]$//'` - compile $a $BASE.obj - OBJECTS="$OBJECTS $BASE.obj" - done - - LDFILE=TMP$$.lk - if [ "x$OUTPUT" = "x" ]; then - OUTPUT=a.out - fi - echo "name $OUTPUT.exe $LDOPTS FIL `fixpath $OBJECTS | sed -e 's/ /,/g'` $LIBRARIES" >$LDFILE - OK=`do_cmd wlink @$LDFILE | check_linker_error` - if [ x$OK != xok ]; then - exit 1 - fi - TARGET=$OUTPUT.exe - if [ $CLEANUP = yes ]; then - if [ "x$LDFILE" != x ]; then - rm $LDFILE || : - fi - fi - ;; -esac - -if [ -f $ERRORFILE ]; then - cat $ERRORFILE 1>&2 - if grep -iv 'Warning' <$ERRORFILE >/dev/null 2>/dev/null; then - rm $ERRORFILE - exit 1 - fi - rm $ERRORFILE -fi - -if [ "x$TARGET" != x ]; then - if [ ! -f "$TARGET" ]; then - echo "RNTCC: output file not generated" - exit 1 - fi -fi - -if [ $OPERATION = linking ]; then - PWD=`pwd` - echo >$OUTPUT "#!/bin/sh" - echo >>$OUTPUT ". \$NTTOOLS" - echo >>$OUTPUT "set -e" - echo >>$OUTPUT "silent_do_cmd '`fixpath $NTDRIVE$PWD/$TARGET`' \"\$@\"" - echo >>$OUTPUT "exit \$?" - chmod +x $OUTPUT -fi +int main(int argc, string *argv) +{ + string target; + string operation="link"; + string *cflags=({}); + string *ldopts=({"OPTION","STACK=8m"}); + string *libraries=({}); + string *objects=({}); + string *sources=({}); + int debug,optimize; + string output; + + mixed *opts=Getopt.find_all_options(argv, ({ + ({"oper_pre",Getopt.NO_ARG, ({"-E"}) }), + ({"oper_comp",Getopt.NO_ARG, ({"-c"}) }), + ({"debug",Getopt.MAY_HAVE_ARG, ({"-g"}) }), + ({"optimize",Getopt.MAY_HAVE_ARG, ({"-O"}) }), + ({"include",Getopt.HAS_ARG, ({"-I"}) }), + ({"link",Getopt.HAS_ARG, ({"-l"}) }), + ({"ignore",Getopt.MAY_HAVE_ARG, ({"-t","-s"}) }), + ({"ignore",Getopt.HAS_ARG, ({"-R","-L"}) }), + ({"warn",Getopt.MAY_HAVE_ARG, ({"-W"}) }), + ({"define",Getopt.HAS_ARG, ({"-D"}) }), + ({"undefine",Getopt.HAS_ARG, ({"-U"})}), + ({"output",Getopt.HAS_ARG, ({"-o"}) }) + })); + foreach(opts, mixed *option) + { + switch(option[0]) + { + case "oper_pre": operation="preprocess"; break; + case "oper_comp": operation="compile"; break; + case "debug": + cflags+=({"-d2"}); + ldopts+=({"DEBUG","WATCOM","ALL"}); + debug=1; + break; + + case "optimize": + if(!option[1]) option[1]=1; + switch(optimize=(int)option[1]) + { + case 0: optimize=0; break; + case 1: cflags+=({"-ox"}); break; + case 2..: cflags+=({"-otexan"}); break; + } + break; + + case "include": + if(sscanf(option[1],"/usr/include/%*s") || + sscanf(option[1],"/usr/local/%*s")) + break; + + cflags+=({"-i"+fixpath(option[1])}); + break; + + case "link": + if(option[1]=="m" || option[1]=="c") break; + + libraries+=({"LIBRARY",option[1]}); + break; + + case "warn": + if(option[1] && sscanf(option[1],"l,%*s")) break; + switch(option[1]) + { + case "all": cflags+=({"-wx"}); break; + default: cflags+=({"-w2"}); break; + } + break; + + case "define": cflags+=({"-d"+option[1]}); break; + case "undefine": cflags+=({"-u"+option[1]}); break; + case "output": + output=option[1]; + break; + } + } + + argv=Getopt.get_args(argv); + foreach(argv[1..], string tmp) + { + string ext; + if(tmp[0]=='-') + { + werror("Unrecognized option "+tmp+".\n"); + exit(1); + } + sscanf(reverse(tmp),"%s.",ext); + switch(ext) + { + case "o": + case "a": + objects+=({tmp}); + break; + + default: + sources+=({tmp}); + } + } + + if(output) rm(output); + + string errorfile="TMP"+getpid()+".err"; + rm(errorfile); + + cflags+=({"-bm","-zq","-hw"}); + + switch(operation) + { + default: + werror("Unknown operation "+operation+".\n"); + exit(1); + + case "compile": + compile(sources,output,errorfile,cflags); + break; + + case "preprocess": + { + int ret=silent_do_cmd( ({"wcc386","-p","-fr"+errorfile}) + cflags + Array.map(sources, fixpath)); + break; + } + + case "link": + foreach(sources, string source) + { + string obj=reverse(source); + sscanf(obj,"%*s.%s",obj); + obj=reverse(obj)+".obj"; + + compile( ({source}), obj, errorfile, cflags); + objects+=({obj}); + check_errorfile(errorfile); + } + + string ldfile="TMP"+getpid()+".lk"; + if(!output) output="a.out"; + rm(ldfile); + Stdio.write_file(ldfile, + "NAME "+output+".exe " + +ldopts*" "+" "+ + "FIL "+Array.map(objects,fixpath)*","+" "+ + libraries*" "+" "); + + do_cmd( ({"wlink","@"+ldfile }), lambda(string data) + { + if(search(data," W1008:")!=-1) + exit(1); + }); + + target=output+".exe"; + + if(getenv("CLEANUP")!="no") + rm(ldfile); + } + + check_errorfile(errorfile); + + if(target) + { + if(!file_stat(target)) + { + werror("RNTCC: output file not generated.\n"); + exit(1); + } + } + + if(operation == "link") + { + rm(output); + Stdio.write_file(output, + "#!/usr/local/bin/pike\n" + "inherit \""+find_lib_location()+"\";\n" + "int main(int argc, string *argv) {\n" + "argv[0]+=\".exe\";\n" + "argv[0]=getenv(\"NTDRIVE\")+fixpath(combine_path(getcwd(),argv[0]));\n" + " exit(silent_do_cmd(argv));\n" + "}\n"); + chmod(output,0755); + } + exit(0); +} diff --git a/NT/tools/sprsh b/NT/tools/sprsh index cb463c2ce0..dbb76418af 100755 --- a/NT/tools/sprsh +++ b/NT/tools/sprsh @@ -1,42 +1,9 @@ #!/usr/local/bin/pike -inherit Stdio.File; - -string handle_input() -{ - object stdin=Stdio.File("stdin"); - while(string s=stdin->read(1000,1)) - write(s); -} +inherit "lib.pike"; -#if !constant(strerror) -#define strerror(X) X -#endif - int main(int argc, string *cmd) { - if(!connect(getenv("NTHOST"),(int)getenv("NTPORT"))) - { - werror("Failed to connect "+strerror(errno())+".\n"); - exit(1); - } - - string tmp=getcwd(); - string mnt=getenv("NTMOUNT"); - if(mnt && strlen(mnt)) tmp=replace(tmp,mnt,""); - cmd[0]=getenv("NTDRIVE")+replace(tmp,"/","\\"); - write(sprintf("%4c",sizeof(cmd))); - for(int e=0;e<sizeof(cmd);e++) - write(sprintf("%4c%s",strlen(cmd[e]),cmd[e])); - - thread_create(handle_input); - while(1) - { - sscanf(read(4),"%4c",int len); - if(!len) break; - predef::write(read(len)); - } - sscanf(read(4),"%4c",int code); - exit(code); + exit(silent_do_cmd(cmd[1..])); } diff --git a/NT/tools/sprshd b/NT/tools/sprshd index a3d17f9863..34710f8d52 100755 --- a/NT/tools/sprshd +++ b/NT/tools/sprshd @@ -22,7 +22,11 @@ void handle_incoming_connection(object(Stdio.File) io) } object pi=Stdio.File(); +#if constant(Stdio.PROP_IPC) + object p2=pi->pipe(Stdio.PROP_IPC); +#else object p2=pi->pipe(); +#endif string dir=cmd[0]; cmd=cmd[1..]; @@ -44,11 +48,31 @@ void handle_incoming_connection(object(Stdio.File) io) string to=combine_path(combine_path(getcwd(),dir),cmd[2]); if(mixed stat=file_stat(to)) + { if(stat[1]==-2) - to=combine_path(to,cmd[1]); + { + to=combine_path(to,basename(cmd[1])); + } + } + + int ret=Stdio.cp(from,to); + if(!ret) + { + string x=sprintf("Errno is %d\n" + "CWD=%s\n" + "from=%s\n" + "to=%s\n" + "dir=%s (%s)\n", + errno(), + getcwd(), + from, + to, + dir, combine_path(getcwd(),dir)); + io->write(sprintf("%4c%s",strlen(x),x)); + } io->write(sprintf("%4c",0)); - io->write(sprintf("%4c",!Stdio.cp(from,to))); + io->write(sprintf("%4c",!ret)); break; } case "getenv": @@ -74,7 +98,9 @@ void handle_incoming_connection(object(Stdio.File) io) if(!err) { +#if !constant(Process.PROP_IPC) thread_create(monitor,p2,p); +#endif while(1) { string s=pi->read(1000,1); @@ -94,7 +120,6 @@ void handle_incoming_connection(object(Stdio.File) io) destruct(io); } - int main(int argc, string *argv) { if(argc<2) diff --git a/src/builtin_functions.c b/src/builtin_functions.c index ac872ecf55..9cfd909b0f 100644 --- a/src/builtin_functions.c +++ b/src/builtin_functions.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: builtin_functions.c,v 1.65 1998/01/30 06:19:50 hubbe Exp $"); +RCSID("$Id: builtin_functions.c,v 1.66 1998/02/01 02:07:22 hubbe Exp $"); #include "interpret.h" #include "svalue.h" #include "pike_macros.h" @@ -356,7 +356,8 @@ void f_add_constant(INT32 args) #define IS_ABS(X) (IS_SEP((X)[0])?1:0) #else #define IS_SEP(X) ( (X) == '/' || (X) == '\\' ) -#define IS_ABS(X) (IS_SEP((X)[0])?1:(isalpha((X)[0]) && (X)[1]==':' && IS_SEP((X)[2]))?3:0) +#define IS_ABS(X) ((isalpha((X)[0]) && (X)[1]==':' && IS_SEP((X)[2]))?3:0) +#define IS_ROOT(X) (IS_SEP((X)[0])?1:0) #endif static char *combine_path(char *cwd,char *file) @@ -369,13 +370,28 @@ static char *combine_path(char *cwd,char *file) my_cwd=0; - if(IS_ABS(file)) + if(IS_ABS(file) +#ifdef IS_ROOT + || ( IS_ROOT(file) && !IS_ABS(cwd)) +#endif + ) { MEMCPY(cwdbuf,file,IS_ABS(file)); cwdbuf[IS_ABS(file)]=0; cwd=cwdbuf; file+=IS_ABS(file); } + +#ifdef IS_ROOT + else if(IS_ROOT(file) && IS_ABS(cwd)) + { + MEMCPY(cwdbuf,cwd,IS_ABS(cwd)); + cwdbuf[IS_ABS(cwd)]=0; + cwd=cwdbuf; + file+=IS_ROOT(file); + } +#endif + #ifdef DEBUG if(!cwd) fatal("No cwd in combine_path!\n"); diff --git a/src/error.c b/src/error.c index 3acf9da06c..c2474a3185 100644 --- a/src/error.c +++ b/src/error.c @@ -29,7 +29,7 @@ JMP_BUF *init_recovery(JMP_BUF *r) return r; } -void pike_throw() ATTRIBUTE((noreturn)) +void pike_throw(void) ATTRIBUTE((noreturn)) { while(recoveries && throw_severity > recoveries->severity) { @@ -143,7 +143,7 @@ void error(char *fmt,...) ATTRIBUTE((noreturn,format (printf, 1, 2))) } -void fatal(char *fmt, ...) ATTRIBUTE((noreturn,format (printf, 1, 2))) +void debug_fatal(char *fmt, ...) ATTRIBUTE((noreturn,format (printf, 1, 2))) { va_list args; static int in_fatal = 0; diff --git a/src/error.h b/src/error.h index 2353b9697e..bd3f6e03a9 100644 --- a/src/error.h +++ b/src/error.h @@ -82,9 +82,12 @@ void va_error(char *fmt, va_list args) ATTRIBUTE((noreturn)); void exit_on_error(void *msg); void fatal_on_error(void *msg); void error(char *fmt,...) ATTRIBUTE((noreturn,format (printf, 1, 2))); -void fatal(char *fmt, ...) ATTRIBUTE((noreturn,format (printf, 1, 2))); +void debug_fatal(char *fmt, ...) ATTRIBUTE((noreturn,format (printf, 1, 2))); /* Prototypes end here */ +#define fatal \ + fprintf(stderr,"Fatal error at %s:%d\n",__FILE__,__LINE__),debug_fatal + #endif diff --git a/src/fdlib.c b/src/fdlib.c index b677f4a9ff..fb6ecc888d 100644 --- a/src/fdlib.c +++ b/src/fdlib.c @@ -1,8 +1,15 @@ #include "fdlib.h" +#include "error.h" #include <math.h> #ifdef HAVE_WINSOCK2_H +#ifdef _REENTRANT +#include "threads.h" + +static MUTEX_T fd_mutex; +#endif + long da_handle[MAX_OPEN_FILEDESCRIPTORS]; int fd_type[MAX_OPEN_FILEDESCRIPTORS]; int first_free_handle; @@ -48,6 +55,8 @@ void fd_init() int e; WSADATA wsadata; + mt_init(&fd_mutex); + mt_lock(&fd_mutex); if(WSAStartup(MAKEWORD(2,0), &wsadata) != 0) { fatal("No winsock available.\n"); @@ -65,11 +74,13 @@ void fd_init() for(e=3;e<MAX_OPEN_FILEDESCRIPTORS-1;e++) fd_type[e]=e+1; fd_type[e]=FD_NO_MORE_FREE; + mt_unlock(&fd_mutex); } void fd_exit() { WSACleanup(); + mt_destroy(&fd_mutex); } FD fd_open(char *file, int open_mode, int create_mode) @@ -134,12 +145,15 @@ FD fd_open(char *file, int open_mode, int create_mode) return -1; } + mt_lock(&fd_mutex); fd=first_free_handle; first_free_handle=fd_type[fd]; fd_type[fd]=FD_FILE; da_handle[fd]=(long)x; + mt_unlock(&fd_mutex); + FDDEBUG(fprintf(stderr,"Opened %s file as %d (%d)\n",file,fd,x)); return fd; @@ -149,22 +163,29 @@ FD fd_socket(int domain, int type, int proto) { FD fd; SOCKET s; + mt_lock(&fd_mutex); if(first_free_handle == FD_NO_MORE_FREE) { + mt_unlock(&fd_mutex); errno=EMFILE; return -1; } + mt_unlock(&fd_mutex); + s=socket(domain, type, proto); + if(s==INVALID_SOCKET) { errno=WSAGetLastError(); return -1; } + mt_lock(&fd_mutex); fd=first_free_handle; first_free_handle=fd_type[fd]; fd_type[fd]=FD_SOCKET; da_handle[fd]=(long)s; + mt_unlock(&fd_mutex); FDDEBUG(fprintf(stderr,"New socket: %d (%d)\n",fd,s)); @@ -174,17 +195,21 @@ FD fd_socket(int domain, int type, int proto) int fd_pipe(int fds[2]) { HANDLE files[2]; + mt_lock(&fd_mutex); if(first_free_handle == FD_NO_MORE_FREE) { + mt_unlock(&fd_mutex); errno=EMFILE; return -1; } + mt_unlock(&fd_mutex); if(!CreatePipe(&files[0], &files[1], NULL, 0)) { errno=GetLastError(); return -1; } + mt_lock(&fd_mutex); fds[0]=first_free_handle; first_free_handle=fd_type[fds[0]]; fd_type[fds[0]]=FD_PIPE; @@ -195,6 +220,7 @@ int fd_pipe(int fds[2]) fd_type[fds[1]]=FD_PIPE; da_handle[fds[1]]=(long)files[1]; + mt_unlock(&fd_mutex); FDDEBUG(fprintf(stderr,"New pipe: %d (%d) -> %d (%d)\n",fds[0],files[0], fds[1], fds[1]));; return 0; @@ -204,18 +230,23 @@ FD fd_accept(FD fd, struct sockaddr *addr, int *addrlen) { FD new_fd; SOCKET s; + mt_lock(&fd_mutex); FDDEBUG(fprintf(stderr,"Accept on %d (%d)..\n",fd,da_handle[fd])); if(first_free_handle == FD_NO_MORE_FREE) { + mt_unlock(&fd_mutex); errno=EMFILE; return -1; } if(fd_type[fd]!=FD_SOCKET) { + mt_unlock(&fd_mutex); errno=ENOTSUPP; return -1; } - s=accept((SOCKET)da_handle[fd], addr, addrlen); + s=(SOCKET)da_handle[fd]; + mt_unlock(&fd_mutex); + s=accept(s, addr, addrlen); if(s==INVALID_SOCKET) { errno=WSAGetLastError(); @@ -223,6 +254,7 @@ FD fd_accept(FD fd, struct sockaddr *addr, int *addrlen) return -1; } + mt_lock(&fd_mutex); new_fd=first_free_handle; first_free_handle=fd_type[new_fd]; fd_type[new_fd]=FD_SOCKET; @@ -230,6 +262,8 @@ FD fd_accept(FD fd, struct sockaddr *addr, int *addrlen) FDDEBUG(fprintf(stderr,"Accept on %d (%d) returned new socket: %d (%d)\n",fd,da_handle[fd],new_fd,s)); + mt_unlock(&fd_mutex); + return new_fd; } @@ -237,10 +271,14 @@ FD fd_accept(FD fd, struct sockaddr *addr, int *addrlen) #define SOCKFUN(NAME,X1,X2) \ int PIKE_CONCAT(fd_,NAME) X1 { SOCKET ret; \ FDDEBUG(fprintf(stderr, #NAME " on %d (%d)\n",fd,da_handle[fd])); \ + mt_lock(&fd_mutex); \ if(fd_type[fd] != FD_SOCKET) { \ + mt_unlock(&fd_mutex); \ errno=ENOTSUPP; \ return -1; \ } \ + ret=(SOCKET)da_handle[fd]; \ + mt_unlock(&fd_mutex); \ ret=NAME X2; \ if(ret == SOCKET_ERROR) errno=WSAGetLastError(); \ FDDEBUG(fprintf(stderr, #NAME " returned %d (%d)\n",ret,errno)); \ @@ -248,25 +286,26 @@ int PIKE_CONCAT(fd_,NAME) X1 { SOCKET ret; \ } #define SOCKFUN1(NAME,T1) \ - SOCKFUN(NAME, (FD fd, T1 a), ((SOCKET)da_handle[fd], a) ) + SOCKFUN(NAME, (FD fd, T1 a), (ret, a) ) #define SOCKFUN2(NAME,T1,T2) \ - SOCKFUN(NAME, (FD fd, T1 a, T2 b), ((SOCKET)da_handle[fd], a, b) ) + SOCKFUN(NAME, (FD fd, T1 a, T2 b), (ret, a, b) ) #define SOCKFUN3(NAME,T1,T2,T3) \ - SOCKFUN(NAME, (FD fd, T1 a, T2 b, T3 c), ((SOCKET)da_handle[fd], a, b, c) ) + SOCKFUN(NAME, (FD fd, T1 a, T2 b, T3 c), (ret, a, b, c) ) #define SOCKFUN4(NAME,T1,T2,T3,T4) \ - SOCKFUN(NAME, (FD fd,T1 a,T2 b,T3 c,T4 d), ((SOCKET)da_handle[fd],a,b,c,d) ) + SOCKFUN(NAME, (FD fd,T1 a,T2 b,T3 c,T4 d), (ret,a,b,c,d) ) #define SOCKFUN5(NAME,T1,T2,T3,T4,T5) \ - SOCKFUN(NAME, (FD fd,T1 a,T2 b,T3 c,T4 d,T5 e), ((SOCKET)da_handle[fd],a,b,c,d,e)) + SOCKFUN(NAME, (FD fd,T1 a,T2 b,T3 c,T4 d,T5 e), (ret,a,b,c,d,e)) SOCKFUN2(bind, struct sockaddr *, int) int fd_connect (FD fd, struct sockaddr *a, int len) { SOCKET ret; + mt_lock(&fd_mutex); FDDEBUG(fprintf(stderr, "connect on %d (%d)\n",fd,da_handle[fd]); for(ret=0;ret<len;ret++) fprintf(stderr," %02x",((unsigned char *)a)[ret]); @@ -274,10 +313,13 @@ int fd_connect (FD fd, struct sockaddr *a, int len) ) if(fd_type[fd] != FD_SOCKET) { + mt_unlock(&fd_mutex); errno=ENOTSUPP; return -1; } - ret=connect((SOCKET)da_handle[fd],a,len); + ret=(SOCKET)da_handle[fd]; + mt_unlock(&fd_mutex); + ret=connect(ret,a,len); if(ret == SOCKET_ERROR) errno=WSAGetLastError(); FDDEBUG(fprintf(stderr, "connect returned %d (%d)\n",ret,errno)); return (int)ret; @@ -294,40 +336,61 @@ SOCKFUN1(listen, int) int fd_close(FD fd) { + HANDLE h; + mt_lock(&fd_mutex); + h=(HANDLE)da_handle[fd]; FDDEBUG(fprintf(stderr,"Closing %d (%d)\n",fd,da_handle[fd])); - if(!CloseHandle((HANDLE)da_handle[fd])) + mt_unlock(&fd_mutex); + if(!CloseHandle(h)) { errno=GetLastError(); return -1; } - fd_type[fd]=first_free_handle; - first_free_handle=fd; + mt_lock(&fd_mutex); + if(fd_type[fd]<FD_NO_MORE_FREE) + { + fd_type[fd]=first_free_handle; + first_free_handle=fd; + } + mt_unlock(&fd_mutex); + return 0; } long fd_write(FD fd, void *buf, long len) { DWORD ret; + long handle; + mt_lock(&fd_mutex); FDDEBUG(fprintf(stderr,"Writing %d bytes to %d (%d)\n",len,fd,da_handle[fd])); - switch(fd_type[fd]) + ret=fd_type[fd]; + handle=da_handle[fd]; + mt_unlock(&fd_mutex); + + switch(ret) { case FD_SOCKET: - ret=send((SOCKET)da_handle[fd], buf, len, 0); + ret=send((SOCKET)handle, buf, len, 0); if(ret<0) { errno=WSAGetLastError(); + FDDEBUG(fprintf(stderr,"Write on %d failed (%d)\n",fd,errno)); return -1; } + FDDEBUG(fprintf(stderr,"Wrote %d bytes to %d)\n",len,fd)); return ret; case FD_CONSOLE: case FD_FILE: case FD_PIPE: - if(!WriteFile((HANDLE)da_handle[fd], buf, len, &ret,0) && !ret) + ret=0; + if(!WriteFile((HANDLE)handle, buf, len, &ret,0) && ret<=0) { errno=GetLastError(); + FDDEBUG(fprintf(stderr,"Write on %d failed (%d)\n",fd,errno)); return -1; } + FDDEBUG(fprintf(stderr,"Wrote %d bytes to %d)\n",len,fd)); return ret; default: @@ -339,30 +402,39 @@ long fd_write(FD fd, void *buf, long len) long fd_read(FD fd, void *to, long len) { DWORD ret; + int rret; + long handle; + + mt_lock(&fd_mutex); FDDEBUG(fprintf(stderr,"Reading %d bytes from %d (%d) to %lx\n",len,fd,da_handle[fd],(int)(char *)to)); - switch(fd_type[fd]) + ret=fd_type[fd]; + handle=da_handle[fd]; + mt_unlock(&fd_mutex); + + switch(ret) { case FD_SOCKET: - ret=recv((SOCKET)da_handle[fd], to, len, 0); - if(ret<0) + rret=recv((SOCKET)handle, to, len, 0); + if(rret<0) { errno=WSAGetLastError(); + FDDEBUG(fprintf(stderr,"Read on %d failed %ld\n",fd,errno)); return -1; } - FDDEBUG(fprintf(stderr,"Read returned %ld\n",ret)); - return ret; + FDDEBUG(fprintf(stderr,"Read on %d returned %ld\n",fd,rret)); + return rret; case FD_CONSOLE: case FD_FILE: case FD_PIPE: ret=0; - if(!ReadFile((HANDLE)da_handle[fd], to, len, &ret,0) && !ret) + if(!ReadFile((HANDLE)handle, to, len, &ret,0) && ret<=0) { errno=GetLastError(); FDDEBUG(fprintf(stderr,"Read failed %d\n",errno)); return -1; } - FDDEBUG(fprintf(stderr,"Read returned %ld\n",ret)); + FDDEBUG(fprintf(stderr,"Read on %d returned %ld\n",fd,ret)); return ret; default: @@ -374,13 +446,17 @@ long fd_read(FD fd, void *to, long len) long fd_lseek(FD fd, long pos, int where) { long ret; + mt_lock(&fd_mutex); if(fd_type[fd]!=FD_FILE) { + mt_unlock(&fd_mutex); errno=ENOTSUPP; return -1; } + ret=da_handle[fd]; + mt_unlock(&fd_mutex); - ret=LZSeek(da_handle[fd], pos, where); + ret=LZSeek((HANDLE)ret, pos, where); if(ret<0) { errno=GetLastError(); @@ -401,12 +477,13 @@ static long convert_filetime_to_time_t(FILETIME tmp) 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; + mt_unlock(&fd_mutex); return -1; } @@ -494,10 +571,12 @@ FD fd_dup(FD from) return -1; } + mt_lock(&fd_mutex); fd=first_free_handle; first_free_handle=fd_type[fd]; fd_type[fd]=fd_type[from]; da_handle[fd]=(long)x; + mt_unlock(&fd_mutex); FDDEBUG(fprintf(stderr,"Dup %d (%d) to %d (%d)\n",from,da_handle[from],fd,x)); return fd; @@ -512,11 +591,13 @@ FD fd_dup2(FD from, FD to) return -1; } + mt_lock(&fd_mutex); if(fd_type[to] < FD_NO_MORE_FREE) { if(!CloseHandle((HANDLE)da_handle[to])) { errno=GetLastError(); + mt_unlock(&fd_mutex); return -1; } }else{ @@ -532,6 +613,7 @@ FD fd_dup2(FD from, FD to) } fd_type[to]=fd_type[from]; da_handle[to]=(long)x; + mt_unlock(&fd_mutex); FDDEBUG(fprintf(stderr,"Dup2 %d (%d) to %d (%d)\n",from,da_handle[from],to,x)); diff --git a/src/fdlib.h b/src/fdlib.h index 272b3553cf..50bbd8ae6b 100644 --- a/src/fdlib.h +++ b/src/fdlib.h @@ -51,7 +51,7 @@ typedef int FD; /* Prototypes begin here */ char *fd_info(int fd); -int fd_query_query_properties(int fd, int guess); +int fd_query_properties(int fd, int guess); void fd_init(); void fd_exit(); FD fd_open(char *file, int open_mode, int create_mode); @@ -94,6 +94,9 @@ struct fd_data_hash_block; int get_fd_data_key(void); void store_fd_data(FD fd, int key, void *data); void *get_fd_data(FD fd, int key); +struct event; +struct fd_waitor; +void fd_waitor_set_customer(struct fd_waitor *x, FD customer, int flags); /* Prototypes end here */ #undef SOCKFUN1 diff --git a/src/interpret.c b/src/interpret.c index 22404a8aee..db8dce364b 100644 --- a/src/interpret.c +++ b/src/interpret.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: interpret.c,v 1.64 1998/01/30 20:04:32 hubbe Exp $"); +RCSID("$Id: interpret.c,v 1.65 1998/02/01 02:07:24 hubbe Exp $"); #include "interpret.h" #include "object.h" #include "program.h" @@ -1082,6 +1082,24 @@ static int eval_instruction(unsigned char *pc) } break; +#ifdef F_ASSIGN_ARRAY + CASE(F_ASSIGN_ARRAY); + { + struct svalue *base=*--mark_sp; + INT32 e,args=(sp-base)>>1 + if(sp[-1].type != T_ARRAY) + error("Bad argument to multiple assign, not an array.\n"); + if(sp[-1].u.array->size < args) + error("Not enough elements in array for multiple assign.\n"); + + for(e=0;e<args;e++) + assign_lvalue(base+e*2,sp[-1].u.array->item+e); + + pop_n_elems(sp-base); + break; + } +#endif + /* Stack machine stuff */ CASE(F_POP_VALUE); pop_stack(); break; CASE(F_POP_N_ELEMS); pop_n_elems(GET_ARG()); break; diff --git a/src/modules/files/file.c b/src/modules/files/file.c index 9f73cd8cdb..8249689e78 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.72 1998/01/30 06:20:54 hubbe Exp $"); +RCSID("$Id: file.c,v 1.73 1998/02/01 02:08:24 hubbe Exp $"); #include "fdlib.h" #include "interpret.h" #include "svalue.h" @@ -1116,6 +1116,8 @@ retry_connect: retry_accept: sv[0]=fd_accept(fd,(struct sockaddr *)&addr,&len); + set_nonblocking(sv[0],0); + if(sv[0] < 0) { if(errno==EINTR) goto retry_accept; fd_close(sv[1]); @@ -1616,10 +1618,14 @@ static void *proxy_thread(void * data) char buffer[READ_BUFFER]; struct new_thread_data *p=(struct new_thread_data *)data; +/* fprintf(stderr,"new proxy thread, from %d to %d.\n",p->fromfd,p->tofd); */ +/* fprintf(stderr,"Thread started %p.\n",p); */ while(1) { long len, w; +/* fprintf(stderr,"reading from %d.\n",p->fromfd); */ len=fd_read(p->fromfd, buffer, READ_BUFFER); + if(len==0) break; if(len<0) { if(errno==EINTR) continue; @@ -1627,17 +1633,24 @@ static void *proxy_thread(void * data) } w=0; +/* fprintf(stderr,"writing to %d.\n",p->tofd); */ while(w<len) { long wl=fd_write(p->tofd, buffer+w, len-w); - if(wl<0) if(errno==EINTR) continue; + if(wl<0) + { + if(errno==EINTR) continue; + break; + } w+=wl; } } +/* fprintf(stderr,"Proxy thread (%d - %d) done.\n",p->fromfd,p->tofd); */ mt_lock(&interpreter_lock); free_object(p->from); free_object(p->to); + num_threads--; mt_unlock(&interpreter_lock); free((char *)p); return 0; @@ -1648,7 +1661,7 @@ void file_proxy(INT32 args) struct file_struct *f; struct new_thread_data *p; THREAD_T id; - check_all_args("Stdio.File->proxy",args, T_OBJECT,0); + check_all_args("Stdio.File->proxy",args, BIT_OBJECT,0); f=(struct file_struct *)get_storage(sp[-args].u.object, file_program); if(!f) error("Bad argument 1 to Stdio.File->proxy, not a Stdio.File object.\n"); @@ -1660,7 +1673,8 @@ void file_proxy(INT32 args) p->fromfd=f->fd; p->to->refs++; p->from->refs++; - if(th_create_small(&id,new_thread_func,p)) + num_threads++; + if(th_create_small(&id,proxy_thread,p)) { free((char *)p); error("Failed to create thread.\n"); @@ -1677,6 +1691,7 @@ void create_proxy_pipe(struct object *o, int for_reading) push_int(fd_INTERPROCESSABLE); apply(n,"pipe",1); n2=sp[-1].u.object; + /* Stack is now: pipe(read), pipe(write) */ if(for_reading) { ref_push_object(o); diff --git a/src/modules/files/socket.c b/src/modules/files/socket.c index 511b95d8af..76e052bf24 100644 --- a/src/modules/files/socket.c +++ b/src/modules/files/socket.c @@ -370,12 +370,11 @@ static void socket_query_address(INT32 args) static void init_port_struct(struct object *o) { THIS->fd=-1; - THIS->id.type=T_OBJECT; + THIS->id.type=T_INT; #ifdef __CHECKER__ THIS->id.subtype=0; #endif - THIS->id.u.object=o; - o->refs++; + THIS->id.u.integer=0; THIS->accept_callback.type=T_INT; THIS->my_errno=0; } diff --git a/src/pike_memory.c b/src/pike_memory.c index ad3860956c..78625cd05b 100644 --- a/src/pike_memory.c +++ b/src/pike_memory.c @@ -788,6 +788,7 @@ static void cleanup_memhdrs() int main(int argc, char *argv[]) { extern int dbm_main(int, char **); + mt_init(&debug_malloc_mutex); atexit(cleanup_memhdrs); return dbm_main(argc, argv); } diff --git a/src/program.h b/src/program.h index 76d244a394..4d7c64cdc2 100644 --- a/src/program.h +++ b/src/program.h @@ -170,7 +170,7 @@ struct inherit #define PROGRAM_PASS_1_DONE 8 /* Program will be destructed as soon at it runs out of references. */ -#define PROGRAM_DESTRUCT_IMMEDIATE 15 +#define PROGRAM_DESTRUCT_IMMEDIATE 16 struct program { diff --git a/src/signal_handler.c b/src/signal_handler.c index cd7a10021d..cd98e0e731 100644 --- a/src/signal_handler.c +++ b/src/signal_handler.c @@ -555,12 +555,12 @@ static HANDLE get_inheritable_handle(struct mapping *optional, apply(tmp->u.object,"query_fd",0); if(sp[-1].type == T_INT) { - if(!(fd_query_properties(sp[-1].u.integer) & fd_INTERPROCESSABLE)) + if(!(fd_query_properties(sp[-1].u.integer, 0) & fd_INTERPROCESSABLE)) { void create_proxy_pipe(struct object *o, int for_reading); - + create_proxy_pipe(tmp->u.object, for_reading); - apply(sp[-1].u.object, "query_fd", 0); + apply(sp[-1].u.object, "query_fd", 0); } @@ -669,13 +669,13 @@ void f_create_process(INT32 args) if(tmp->type == T_STRING) dir=convert_string(tmp->u.string->str, tmp->u.string->len); - t1=get_inheritable_handle(optional, "stdin",0); + t1=get_inheritable_handle(optional, "stdin",1); if(t1!=INVALID_HANDLE_VALUE) info.hStdInput=t1; - t2=get_inheritable_handle(optional, "stdout",1); + t2=get_inheritable_handle(optional, "stdout",0); if(t2!=INVALID_HANDLE_VALUE) info.hStdOutput=t2; - t3=get_inheritable_handle(optional, "stderr",1); + t3=get_inheritable_handle(optional, "stderr",0); if(t3!=INVALID_HANDLE_VALUE) info.hStdError=t3; if((tmp=simple_mapping_string_lookup(optional, "env"))) -- GitLab