diff --git a/src/modules/files/efuns.c b/src/modules/files/efuns.c index a1c76d098109c40fcae1fc0e896c50fbb82023ca..5bcbf5b2c8e2603ef98552037bae31f22ef9af03 100644 --- a/src/modules/files/efuns.c +++ b/src/modules/files/efuns.c @@ -60,11 +60,13 @@ # endif #endif +#include "dmalloc.h" + #ifdef HAVE_PROCESS_H #include <process.h> #endif -#include "dmalloc.h" +/* #define DEBUG_FILE */ struct array *encode_stat(struct stat *s) { @@ -78,7 +80,12 @@ struct array *encode_stat(struct stat *s) #ifdef S_IFLNK case S_IFLNK: ITEM(a)[1].u.integer=-3; break; #endif - default: ITEM(a)[1].u.integer=-4; break; + default: +#ifdef DEBUG_FILE + fprintf(stderr, "encode_stat(): mode:%ld\n", (long)S_IFMT & s->st_mode); +#endif /* DEBUG_FILE */ + ITEM(a)[1].u.integer=-4; + break; } ITEM(a)[2].u.integer=s->st_atime; ITEM(a)[3].u.integer=s->st_mtime; @@ -102,7 +109,7 @@ void f_file_stat(INT32 args) s = sp[-args].u.string->str; l = (args>1 && !IS_ZERO(sp-1-args))?1:0; - THREADS_ALLOW(); + THREADS_ALLOW_UID(); #ifdef HAVE_LSTAT if(l) i=lstat(s, &st); @@ -110,7 +117,7 @@ void f_file_stat(INT32 args) #endif i=stat(s, &st); - THREADS_DISALLOW(); + THREADS_DISALLOW_UID(); pop_n_elems(args); if(i==-1) { @@ -326,7 +333,7 @@ void f_rm(INT32 args) s = sp[-args].u.string->str; - THREADS_ALLOW(); + THREADS_ALLOW_UID(); #ifdef HAVE_LSTAT i=lstat(s, &st) != -1; #else @@ -341,7 +348,7 @@ void f_rm(INT32 args) i=unlink(s) != -1; } } - THREADS_DISALLOW(); + THREADS_DISALLOW_UID(); pop_n_elems(args); push_int(i); @@ -367,13 +374,13 @@ void f_mkdir(INT32 args) i=sp[1-args].u.integer; } s=sp[-args].u.string->str; - THREADS_ALLOW(); + THREADS_ALLOW_UID(); #if MKDIR_ARGS == 2 i=mkdir(s, i) != -1; #else i=mkdir(s) != -1; #endif - THREADS_DISALLOW(); + THREADS_DISALLOW_UID(); pop_n_elems(args); push_int(i); } @@ -395,9 +402,9 @@ void f_get_dir(INT32 args) get_all_args("get_dir",args,"%s",&path); #if defined(_REENTRANT) && defined(HAVE_READDIR_R) - THREADS_ALLOW(); + THREADS_ALLOW_UID(); dir=opendir(path); - THREADS_DISALLOW(); + THREADS_DISALLOW_UID(); if(dir) { #define FPR 1024 @@ -561,9 +568,9 @@ void f_getcwd(INT32 args) #define MAXPATHLEN 32768 #endif tmp=xalloc(MAXPATHLEN+1); - THREADS_ALLOW(); + THREADS_ALLOW_UID(); e=(char *)getwd(tmp); - THREADS_DISALLOW(); + THREADS_DISALLOW_UID(); #endif if(!e) { if (tmp) diff --git a/src/modules/files/file.c b/src/modules/files/file.c index 518dd81e335a95676f906c75f03adc3d2045db71..b4d51c9ed2c50e349bfbed0e2b53ba539346b7af 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.82 1998/03/26 03:12:39 hubbe Exp $"); +RCSID("$Id: file.c,v 1.83 1998/03/26 14:31:01 grubba Exp $"); #include "fdlib.h" #include "interpret.h" #include "svalue.h" @@ -882,11 +882,11 @@ static void file_open(INT32 args) if(!( flags & (FILE_READ | FILE_WRITE))) error("Must open file for at least one of read and write.\n"); - THREADS_ALLOW(); + THREADS_ALLOW_UID(); do { fd=fd_open(str->str,map(flags), access); } while(fd < 0 && errno == EINTR); - THREADS_DISALLOW(); + THREADS_DISALLOW_UID(); if(!fp->current_object->prog) error("Object destructed in file->open()\n"); diff --git a/src/modules/files/socket.c b/src/modules/files/socket.c index fa157f8daf24f60ac2fbcb189acbd780e3a2f6eb..8b103fc6e692f65c819330fcb67a7591ec752e1c 100644 --- a/src/modules/files/socket.c +++ b/src/modules/files/socket.c @@ -229,9 +229,9 @@ static void port_bind(INT32 args) addr.sin_port = htons( ((u_short)sp[-args].u.integer) ); addr.sin_family = AF_INET; - THREADS_ALLOW(); + THREADS_ALLOW_UID(); tmp=fd_bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0 || fd_listen(fd, 5) < 0; - THREADS_DISALLOW(); + THREADS_DISALLOW_UID(); if(tmp) { diff --git a/src/modules/spider/dumudp.c b/src/modules/spider/dumudp.c index d86d8976cbe968ab9006e66ff8023cac01e04e54..1f1461ce210800905c7427597f590b5704e0c264 100644 --- a/src/modules/spider/dumudp.c +++ b/src/modules/spider/dumudp.c @@ -1,7 +1,7 @@ #include "config.h" #include "global.h" -RCSID("$Id: dumudp.c,v 1.35 1998/03/12 18:44:30 per Exp $"); +RCSID("$Id: dumudp.c,v 1.36 1998/03/26 14:31:02 grubba Exp $"); #include "fdlib.h" #include "interpret.h" #include "svalue.h" @@ -136,8 +136,12 @@ static void udp_bind(INT32 args) addr.sin_port = htons( ((u_short)sp[-args].u.integer) ); addr.sin_family = AF_INET; + THREADS_ALLOW_UID(); + tmp=fd_bind(fd, (struct sockaddr *)&addr, sizeof(addr))<0; + THREADS_DISALLOW_UID(); + if(tmp) { fd_close(fd); diff --git a/src/modules/system/passwords.c b/src/modules/system/passwords.c index 6f962d781cf18fa79512e906a4e7f68b0cfbcd87..55ecf970b1dc35e74038f3d1ac23d575cdf28f25 100644 --- a/src/modules/system/passwords.c +++ b/src/modules/system/passwords.c @@ -1,5 +1,5 @@ /* - * $Id: passwords.c,v 1.6 1998/03/03 10:51:37 mast Exp $ + * $Id: passwords.c,v 1.7 1998/03/26 14:31:02 grubba Exp $ * * Password handling for Pike. * @@ -15,7 +15,7 @@ #include "global.h" -RCSID("$Id: passwords.c,v 1.6 1998/03/03 10:51:37 mast Exp $"); +RCSID("$Id: passwords.c,v 1.7 1998/03/26 14:31:02 grubba Exp $"); #include "module_support.h" #include "interpret.h" @@ -59,7 +59,10 @@ static void push_pwent(struct passwd *ent) if(!strcmp(ent->pw_passwd, "x")) { struct spwd *foo; - if((foo = getspnam(ent->pw_name))) + THREADS_ALLOW_UID(); + foo = getspnam(ent->pw_name); + THREADS_DISALLOW_UID(); + if(foo) push_text(foo->sp_pwdp); else push_text("x"); @@ -103,7 +106,9 @@ void f_getgrgid(INT32 args) int gid; struct group *foo; get_all_args("getgrgid", args, "%d", &gid); + THREADS_ALLOW_UID(); foo = getgrgid( gid ); + THREADS_DISALLOW_UID(); pop_n_elems( args ); push_grent( foo ); } @@ -116,7 +121,9 @@ void f_getgrnam(INT32 args) char *str; struct group *foo; get_all_args("getgrnam", args, "%s", &str); + THREADS_ALLOW_UID(); foo = getgrnam( str ); + THREADS_DISALLOW_UID(); pop_n_elems( args ); push_grent( foo ); } @@ -131,7 +138,9 @@ void f_getpwnam(INT32 args) get_all_args("getpwnam", args, "%s", &str); + THREADS_ALLOW_UID(); foo = getpwnam(str); + THREADS_DISALLOW_UID(); pop_n_elems(args); push_pwent(foo); @@ -147,7 +156,9 @@ void f_getpwuid(INT32 args) get_all_args("getpwuid", args, "%i", &uid); + THREADS_ALLOW_UID(); foo = getpwuid(uid); + THREADS_DISALLOW_UID(); pop_n_elems(args); push_pwent(foo); @@ -158,7 +169,9 @@ void f_getpwuid(INT32 args) /* int setpwent() */ void f_setpwent(INT32 args) { + THREADS_ALLOW(); setpwent(); + THREADS_DISALLOW(); pop_n_elems(args); push_int(0); } @@ -168,7 +181,9 @@ void f_setpwent(INT32 args) /* int endpwent() */ void f_endpwent(INT32 args) { + THREADS_ALLOW(); endpwent(); + THREADS_DISALLOW(); pop_n_elems(args); push_int(0); } @@ -180,7 +195,9 @@ void f_getpwent(INT32 args) { struct passwd *foo; pop_n_elems(args); + THREADS_ALLOW_UID(); foo = getpwent(); + THREADS_DISALLOW_UID(); if(!foo) { push_int(0); @@ -194,7 +211,9 @@ void f_getpwent(INT32 args) /* int setgrent() */ void f_setgrent(INT32 args) { + THREADS_ALLOW(); setgrent(); + THREADS_DISALLOW(); pop_n_elems(args); push_int(0); } @@ -204,7 +223,9 @@ void f_setgrent(INT32 args) /* int endgrent() */ void f_endgrent(INT32 args) { + THREADS_ALLOW(); endgrent(); + THREADS_DISALLOW(); pop_n_elems(args); push_int(0); } @@ -216,7 +237,9 @@ void f_getgrent(INT32 args) { struct group *foo; pop_n_elems(args); + THREADS_ALLOW_UID(); foo = getgrent(); + THREADS_DISALLOW_UID(); if(!foo) { push_int(0); diff --git a/src/modules/system/syslog.c b/src/modules/system/syslog.c index 9249e80da6455d50a8520e1a696951d656560946..972e24937b21c0780d2ccdad000b3c1513e7b680 100644 --- a/src/modules/system/syslog.c +++ b/src/modules/system/syslog.c @@ -1,5 +1,5 @@ /* - * $Id: syslog.c,v 1.4 1997/12/07 21:59:15 grubba Exp $ + * $Id: syslog.c,v 1.5 1998/03/26 14:31:02 grubba Exp $ * * Access to syslog from Pike. * @@ -17,7 +17,7 @@ #ifdef HAVE_SYSLOG -RCSID("$Id: syslog.c,v 1.4 1997/12/07 21:59:15 grubba Exp $"); +RCSID("$Id: syslog.c,v 1.5 1998/03/26 14:31:02 grubba Exp $"); #include "interpret.h" #include "svalue.h" @@ -135,9 +135,13 @@ void f_openlog(INT32 args) if(p_facility & (1<<16)) facility |= LOG_SYSLOG; if(p_facility & (1<<17)) facility |= LOG_USER; if(p_facility & (1<<18)) facility |= LOG_UUCP; + + THREADS_ALLOW(); openlog(ident, option, facility); + THREADS_DISALLOW(); + pop_n_elems(args); } diff --git a/src/modules/system/system.c b/src/modules/system/system.c index 34c7b7b7d84be7295efa11ea8d8c7f351ff5131b..5551153f7eb77f135f6601e2643f51860132b248 100644 --- a/src/modules/system/system.c +++ b/src/modules/system/system.c @@ -1,5 +1,5 @@ /* - * $Id: system.c,v 1.46 1998/03/26 00:52:48 hubbe Exp $ + * $Id: system.c,v 1.47 1998/03/26 14:31:03 grubba Exp $ * * System-call module for Pike * @@ -14,7 +14,7 @@ #include "system.h" #include "global.h" -RCSID("$Id: system.c,v 1.46 1998/03/26 00:52:48 hubbe Exp $"); +RCSID("$Id: system.c,v 1.47 1998/03/26 14:31:03 grubba Exp $"); #ifdef HAVE_WINSOCK_H #include <winsock.h> #endif @@ -172,11 +172,11 @@ void f_hardlink(INT32 args) get_all_args("hardlink",args, "%s%s", &from, &to); - THREADS_ALLOW(); + THREADS_ALLOW_UID(); do { err = link(from, to); } while ((err < 0) && (errno == EINTR)); - THREADS_DISALLOW(); + THREADS_DISALLOW_UID(); if (err < 0) { report_error("hardlink"); @@ -195,11 +195,11 @@ void f_symlink(INT32 args) get_all_args("symlink",args, "%s%s", &from, &to); - THREADS_ALLOW(); + THREADS_ALLOW_UID(); do { err = symlink(from, to); } while ((err < 0) && (errno == EINTR)); - THREADS_DISALLOW(); + THREADS_DISALLOW_UID(); if (err < 0) { report_error("symlink"); @@ -227,11 +227,11 @@ void f_readlink(INT32 args) error("readlink(): Out of memory\n"); } - THREADS_ALLOW(); + THREADS_ALLOW_UID(); do { err = readlink(path, buf, buflen); } while ((err < 0) && (errno == EINTR)); - THREADS_DISALLOW(); + THREADS_DISALLOW_UID(); } while (err >= buflen - 1); if (err < 0) { @@ -250,11 +250,11 @@ void f_chmod(INT32 args) int err; get_all_args("chmod", args, "%s%i", &path, &mode); - THREADS_ALLOW(); + THREADS_ALLOW_UID(); do { err = chmod(path, mode); } while ((err < 0) && (errno == EINTR)); - THREADS_DISALLOW(); + THREADS_DISALLOW_UID(); if (err < 0) { report_error("chmod"); } @@ -270,11 +270,11 @@ void f_chown(INT32 args) int err; get_all_args("chown", args, "%s%i%i", &path, &uid, &gid); - THREADS_ALLOW(); + THREADS_ALLOW_UID(); do { err = chown(path, uid, gid); } while((err < 0) && (errno == EINTR)); - THREADS_DISALLOW(); + THREADS_DISALLOW_UID(); if (err < 0) { report_error("chown"); } diff --git a/src/program.c b/src/program.c index fbc06164114246c12604f9d19b0ed0910629d303..b5921c041d02238905d3838e53a05dca1b9f2893 100644 --- a/src/program.c +++ b/src/program.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: program.c,v 1.66 1998/03/18 20:22:31 per Exp $"); +RCSID("$Id: program.c,v 1.67 1998/03/26 14:30:58 grubba Exp $"); #include "program.h" #include "object.h" #include "dynamic_buffer.h" @@ -837,6 +837,7 @@ struct program *end_first_pass(int finish) compilation_depth--; threads_disabled--; + co_signal(&threads_disabled_change); free_all_nodes(); return prog; } diff --git a/src/threads.c b/src/threads.c index 8cfc49b6888c33e1b326f64604420ac52f12fcd6..71cfb189b352f755b1c1591180be574632e03cdc 100644 --- a/src/threads.c +++ b/src/threads.c @@ -1,5 +1,5 @@ #include "global.h" -RCSID("$Id: threads.c,v 1.64 1998/03/26 05:48:24 per Exp $"); +RCSID("$Id: threads.c,v 1.65 1998/03/26 14:30:59 grubba Exp $"); int num_threads = 1; int threads_disabled = 0; @@ -16,6 +16,10 @@ int threads_disabled = 0; #include "gc.h" #include "main.h" +int live_threads = 0; +COND_T live_threads_change; +COND_T threads_disabled_change; + #ifdef __NT__ #ifdef DEBUG @@ -155,11 +159,18 @@ struct thread_starter void exit_threads_disable(struct object *o) { if(threads_disabled) threads_disabled--; + co_broadcast(&threads_disabled_change); } void init_threads_disable(struct object *o) { threads_disabled++; + while (live_threads) { + THREADS_FPRINTF((stderr, + "_disable_threads(): Waiting for %d threads to finish\n", + live_threads)); + co_wait(&live_threads_change, &interpreter_lock); + } } /* Thread hashtable */ @@ -723,6 +734,8 @@ void th_init(void) mt_init( & interpreter_lock); mt_lock( & interpreter_lock); mt_init( & thread_table_lock); + co_init( & live_threads_change); + co_init( & threads_disabled_change); thread_table_init(); #ifdef POSIX_THREADS pthread_attr_init(&pattr); diff --git a/src/threads.h b/src/threads.h index a4c6b961a9191532f2a8e64c1cb53f216165c5aa..ec647a7f5a00e7f60b716fa75b541f8715b46955 100644 --- a/src/threads.h +++ b/src/threads.h @@ -45,6 +45,7 @@ extern int num_threads; +extern int live_threads; struct object; extern struct object *thread_id; @@ -221,6 +222,8 @@ int co_destroy(COND_T *c); extern MUTEX_T interpreter_lock; +extern COND_T live_threads_change; /* Used by _disable_threads */ +extern COND_T threads_disabled_change; /* Used by _disable_threads */ struct svalue; struct frame; @@ -338,8 +341,9 @@ struct thread_state { struct thread_state *_tmp=(struct thread_state *)thread_id->storage; \ if(num_threads > 1 && !threads_disabled) { \ SWAP_OUT_THREAD(_tmp); \ - THREADS_FPRINTF((stderr, "THREADS_ALLOW() %s:%d t:%08x\n", \ - __FILE__, __LINE__, (unsigned int)_tmp->thread_id)); \ + THREADS_FPRINTF((stderr, "THREADS_ALLOW() %s:%d t:%08x (#%d)\n", \ + __FILE__, __LINE__, \ + (unsigned int)_tmp->thread_id, live_threads)); \ mt_unlock(& interpreter_lock); \ } else {} \ HIDE_GLOBAL_VARIABLES() @@ -348,12 +352,46 @@ struct thread_state { REVEAL_GLOBAL_VARIABLES(); \ if(_tmp->swapped) { \ mt_lock(& interpreter_lock); \ - THREADS_FPRINTF((stderr, "THREADS_DISALLOW() %s:%d ... t:%08x\n", \ - __FILE__, __LINE__, (unsigned int)_tmp->thread_id)); \ + THREADS_FPRINTF((stderr, "THREADS_DISALLOW() %s:%d... t:%08x (#%d)\n", \ + __FILE__, __LINE__, \ + (unsigned int)_tmp->thread_id, live_threads)); \ + while (threads_disabled) { \ + THREADS_FPRINTF((stderr, "THREADS_DISALLOW(): Threads disabled\n")); \ + co_wait(&live_threads_change, &interpreter_lock); \ + } \ SWAP_IN_THREAD(_tmp);\ } \ } while(0) +#define THREADS_ALLOW_UID() do { \ + struct thread_state *_tmp_uid=(struct thread_state *)thread_id->storage; \ + if(num_threads > 1 && !threads_disabled) { \ + SWAP_OUT_THREAD(_tmp_uid); \ + live_threads++; \ + THREADS_FPRINTF((stderr, "THREADS_ALLOW() %s:%d t:%08x (#%d)\n", \ + __FILE__, __LINE__, \ + (unsigned int)_tmp_uid->thread_id, live_threads)); \ + mt_unlock(& interpreter_lock); \ + } else {} \ + HIDE_GLOBAL_VARIABLES() + +#define THREADS_DISALLOW_UID() \ + REVEAL_GLOBAL_VARIABLES(); \ + if(_tmp_uid->swapped) { \ + mt_lock(& interpreter_lock); \ + live_threads--; \ + THREADS_FPRINTF((stderr, "THREADS_DISALLOW() %s:%d... t:%08x (#%d)\n", \ + __FILE__, __LINE__, \ + (unsigned int)_tmp_uid->thread_id, live_threads)); \ + while (threads_disabled) { \ + THREADS_FPRINTF((stderr, "THREADS_DISALLOW(): Threads disabled\n")); \ + co_signal(&live_threads_change); \ + co_wait(&threads_disabled_change, &interpreter_lock); \ + } \ + SWAP_IN_THREAD(_tmp_uid);\ + } \ + } while(0) + /* Prototypes begin here */ struct thread_starter; void *new_thread_func(void * data);