diff --git a/lib/master.pike b/lib/master.pike index c739cd9d6ec38e1e7c3749e5b7a4808d804fe8b9..1277bad8bd93298eda55c9f662c095c397d2fe65 100644 --- a/lib/master.pike +++ b/lib/master.pike @@ -1,4 +1,4 @@ -/* $Id: master.pike,v 1.63 1998/01/21 19:36:19 hubbe Exp $ +/* $Id: master.pike,v 1.64 1998/01/28 00:28:18 hubbe Exp $ * * Master-file for Pike. */ @@ -57,7 +57,7 @@ program compile_string(string data, void|string name) program compile_file(string file) { - return compile(cpp(_static_modules.files()->file(file,"r")->read(),file)); + return compile(cpp(_static_modules.files()->File(file,"r")->read(),file)); } @@ -488,7 +488,7 @@ void _main(string *argv, string *env) add_constant("getenv",getenv); add_constant("putenv",putenv); - add_constant("write",_static_modules.files()->file("stdout")->write); + add_constant("write",_static_modules.files()->File("stdout")->write); _master_file_name=backtrace()[-1][0]; q=explode_path(_master_file_name); @@ -727,7 +727,7 @@ string handle_include(string f, string read_include(string f) { - return _static_modules->files()->file(f,"r")->read(); + return _static_modules->files()->File(f,"r")->read(); } // FIXME diff --git a/lib/modules/LR.pmod/Grammar_parser.pmod b/lib/modules/LR.pmod/Grammar_parser.pmod index b287a73b1731e413fc2171dcddeef43d90c5c9e6..3999b96c918dd7be0c9bae0b94a4c5a5dba7ba9f 100755 --- a/lib/modules/LR.pmod/Grammar_parser.pmod +++ b/lib/modules/LR.pmod/Grammar_parser.pmod @@ -1,7 +1,7 @@ #!/home/grubba/src/pike/build/sol2.5/pike /* - * $Id: Grammar_parser.pmod,v 1.4 1997/04/22 00:09:28 grubba Exp $ + * $Id: Grammar_parser.pmod,v 1.5 1998/01/28 00:30:05 hubbe Exp $ * * Generates a parser from a textual specification. * @@ -10,7 +10,7 @@ //. //. File: Grammar_parser.pmod -//. RCSID: $Id: Grammar_parser.pmod,v 1.4 1997/04/22 00:09:28 grubba Exp $ +//. RCSID: $Id: Grammar_parser.pmod,v 1.5 1998/01/28 00:30:05 hubbe Exp $ //. Author: Henrik grubbström (grubba@infovav.se) //. //. Synopsis: Generates an LR parser from a textual specification. @@ -375,7 +375,7 @@ object(parser) make_parser(string str, object|void m) //. SEE ALSO: Grammar_parser.make_parser int|object(parser) make_parser_from_file(string fname, object|void m) { - object(files.file) f = files.file(); + object(Stdio.File) f = Stdio.File(); int|object(parser) g = 0; if (f->open(fname, "r")) { g = make_parser(f->read(0x7fffffff), m); diff --git a/lib/modules/Process.pmod b/lib/modules/Process.pmod index dfa0417077655cefac0e6f229a0122d5a2b03ea0..1ba4be5201801559864e1b9a6f17ac20bd0c10be 100644 --- a/lib/modules/Process.pmod +++ b/lib/modules/Process.pmod @@ -112,7 +112,7 @@ string popen(string s) if (!f) error("Popen failed. (couldn't create pipe)\n"); - p=f->pipe(); + p=f->pipe(Stdio.PROP_IPC); if(!p) error("Popen failed. (couldn't create pipe)\n"); spawn(s,0,p,0, destruct, f); p->close(); diff --git a/lib/modules/Stdio.pmod b/lib/modules/Stdio.pmod index 8b8d994dbe846941f41c854e881850b630a73f5c..a06918ad3735c717460223e206bed84adf47f535 100644 --- a/lib/modules/Stdio.pmod +++ b/lib/modules/Stdio.pmod @@ -1,8 +1,5 @@ #include <string.h> -import files; - -constant File=file; -constant Port=port; +inherit files; object stderr=File("stderr"); object stdout=File("stdout"); diff --git a/src/callback.c b/src/callback.c index 021b2fd07c6e93d80ee082b1e394e5181a29162a..0ff8ca355ce1e3653e9bda54e81b18634f1dab78 100644 --- a/src/callback.c +++ b/src/callback.c @@ -3,6 +3,7 @@ ||| Pike is distributed as GPL (General Public License) ||| See the files COPYING and DISCLAIMER for more information. \*/ +#include "global.h" #include "pike_macros.h" #include "callback.h" #include "error.h" diff --git a/src/configure.in b/src/configure.in index 7ff094d0c11995d33de1cb0490a2d2bcd9091287..226a8890cbdea28d13a5b9b16cf2e25c22d2ee3a 100644 --- a/src/configure.in +++ b/src/configure.in @@ -1,4 +1,4 @@ -AC_REVISION("$Id: configure.in,v 1.153 1998/01/23 02:34:17 grubba Exp $") +AC_REVISION("$Id: configure.in,v 1.154 1998/01/28 00:31:14 hubbe Exp $") AC_INIT(interpret.c) AC_CONFIG_HEADER(machine.h) @@ -1732,7 +1732,7 @@ fi rm -f core -############################################################################# +########################################################################## # Set info about shared libraries. AC_SUBST(SO) diff --git a/src/fdlib.c b/src/fdlib.c index bb7d1f88aa2399ee0bd7744c85485bb8becb04c8..b677f4a9ff0202c905a3db903f072a1e261df6d6 100644 --- a/src/fdlib.c +++ b/src/fdlib.c @@ -7,7 +7,7 @@ long da_handle[MAX_OPEN_FILEDESCRIPTORS]; int fd_type[MAX_OPEN_FILEDESCRIPTORS]; int first_free_handle; -#define FDDEBUG(X) X +#define FDDEBUG(X) char *fd_info(int fd) { @@ -22,10 +22,27 @@ char *fd_info(int fd) case FD_SOCKET: return "IS SOCKET"; case FD_CONSOLE: return "IS CONSOLE"; case FD_FILE: return "IS FILE"; + case FD_PIPE: return "IS PIPE"; default: return "NOT OPEN"; } } +int fd_query_properties(int fd, int guess) +{ + switch(fd_type[fd]) + { + case FD_SOCKET: + return fd_BUFFERED | fd_CAN_NONBLOCK | fd_CAN_SHUTDOWN; + case FD_FILE: + case FD_CONSOLE: + return fd_INTERPROCESSABLE; + + case FD_PIPE: + return fd_INTERPROCESSABLE | fd_BUFFERED; + default: return 0; + } +} + void fd_init() { int e; @@ -137,7 +154,7 @@ FD fd_socket(int domain, int type, int proto) errno=EMFILE; return -1; } - s=WSASocket(domain, type, proto, 0, 0, 0); + s=socket(domain, type, proto); if(s==INVALID_SOCKET) { errno=WSAGetLastError(); @@ -154,10 +171,40 @@ FD fd_socket(int domain, int type, int proto) return fd; } +int fd_pipe(int fds[2]) +{ + HANDLE files[2]; + if(first_free_handle == FD_NO_MORE_FREE) + { + errno=EMFILE; + return -1; + } + if(!CreatePipe(&files[0], &files[1], NULL, 0)) + { + errno=GetLastError(); + return -1; + } + + fds[0]=first_free_handle; + first_free_handle=fd_type[fds[0]]; + fd_type[fds[0]]=FD_PIPE; + da_handle[fds[0]]=(long)files[0]; + + fds[1]=first_free_handle; + first_free_handle=fd_type[fds[1]]; + fd_type[fds[1]]=FD_PIPE; + da_handle[fds[1]]=(long)files[1]; + + FDDEBUG(fprintf(stderr,"New pipe: %d (%d) -> %d (%d)\n",fds[0],files[0], fds[1], fds[1]));; + + return 0; +} + FD fd_accept(FD fd, struct sockaddr *addr, int *addrlen) { FD new_fd; SOCKET s; + FDDEBUG(fprintf(stderr,"Accept on %d (%d)..\n",fd,da_handle[fd])); if(first_free_handle == FD_NO_MORE_FREE) { errno=EMFILE; @@ -168,10 +215,11 @@ FD fd_accept(FD fd, struct sockaddr *addr, int *addrlen) errno=ENOTSUPP; return -1; } - s=WSAAccept((SOCKET)da_handle[fd], addr, addrlen, NULL, 0); + s=accept((SOCKET)da_handle[fd], addr, addrlen); if(s==INVALID_SOCKET) { errno=WSAGetLastError(); + FDDEBUG(fprintf(stderr,"Accept failed with errno %d\n",errno)); return -1; } @@ -216,14 +264,13 @@ int PIKE_CONCAT(fd_,NAME) X1 { SOCKET ret; \ SOCKFUN2(bind, struct sockaddr *, int) -#if 1 int fd_connect (FD fd, struct sockaddr *a, int len) { SOCKET ret; - 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]); - fprintf(stderr,"\n"); + 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]); + fprintf(stderr,"\n"); ) if(fd_type[fd] != FD_SOCKET) { @@ -235,9 +282,6 @@ int fd_connect (FD fd, struct sockaddr *a, int len) FDDEBUG(fprintf(stderr, "connect returned %d (%d)\n",ret,errno)); return (int)ret; } -#else -SOCKFUN2(connect, struct sockaddr *, int) -#endif SOCKFUN4(getsockopt,int,int,void*,int*) SOCKFUN4(setsockopt,int,int,void*,int) SOCKFUN2(getsockname,struct sockaddr *,int *) @@ -278,6 +322,7 @@ long fd_write(FD fd, void *buf, long len) case FD_CONSOLE: case FD_FILE: + case FD_PIPE: if(!WriteFile((HANDLE)da_handle[fd], buf, len, &ret,0) && !ret) { errno=GetLastError(); @@ -309,6 +354,7 @@ long fd_read(FD fd, void *to, long len) case FD_CONSOLE: case FD_FILE: + case FD_PIPE: ret=0; if(!ReadFile((HANDLE)da_handle[fd], to, len, &ret,0) && !ret) { @@ -418,7 +464,7 @@ int fd_select(int fds, FD_SET *a, FD_SET *b, FD_SET *c, struct timeval *t) int fd_ioctl(FD fd, int cmd, void *data) { int ret; - FDEBUG(fprintf("ioctl(%d (%d,%d,%p)\n",fd,da_handle[fd],cmd,data)) + FDDEBUG(fprintf(stderr,"ioctl(%d (%d,%d,%p)\n",fd,da_handle[fd],cmd,data)); switch(fd_type[fd]) { case FD_SOCKET: @@ -740,7 +786,7 @@ struct fd_waitor fd_FDZERO(&X->xcustomers); \ } while(0) -void fd_waitor_set_customer(fd_waitor *x, FD customer, int flags) +void fd_waitor_set_customer(struct fd_waitor *x, FD customer, int flags) { if(flags & FD_EVENT_READ) { diff --git a/src/fdlib.h b/src/fdlib.h index fc7139899d5862e8c91c0c38f1b9a462ca706687..272b3553cf8c79d2bc246fd68e8492d4a65308ee 100644 --- a/src/fdlib.h +++ b/src/fdlib.h @@ -20,9 +20,20 @@ #include <sys/stat.h> #endif + +#define fd_INTERPROCESSABLE 1 +#define fd_CAN_NONBLOCK 2 +#define fd_CAN_SHUTDOWN 4 +#define fd_BUFFERED 8 +#define fd_BIDIRECTIONAL 16 + #ifdef HAVE_WINSOCK2_H +#define FILE_CAPABILITIES (fd_INTERPROCESSABLE) +#define PIPE_CAPABILITIES (fd_INTERPROCESSABLE | fd_BUFFERED) +#define SOCKET_CAPABILITIES (fd_BIDIRECTIONAL | fd_CAN_NONBLOCK | fd_CAN_SHUTDOWN) + #ifndef FD_SETSIZE #define FD_SETSIZE MAX_OPEN_FILEDESCRIPTORS #endif @@ -40,13 +51,15 @@ typedef int FD; /* Prototypes begin here */ char *fd_info(int fd); +int fd_query_query_properties(int fd, int guess); void fd_init(); void fd_exit(); FD fd_open(char *file, int open_mode, int create_mode); FD fd_socket(int domain, int type, int proto); +int fd_pipe(int fds[2]); FD fd_accept(FD fd, struct sockaddr *addr, int *addrlen); SOCKFUN2(bind, struct sockaddr *, int) -SOCKFUN2(connect, struct sockaddr *, int) +int fd_connect (FD fd, struct sockaddr *a, int len); SOCKFUN4(getsockopt,int,int,void*,int*) SOCKFUN4(setsockopt,int,int,void*,int) SOCKFUN2(getsockname,struct sockaddr *,int *) @@ -65,6 +78,22 @@ int fd_select(int fds, FD_SET *a, FD_SET *b, FD_SET *c, struct timeval *t); int fd_ioctl(FD fd, int cmd, void *data); FD fd_dup(FD from); FD fd_dup2(FD from, FD to); +struct fd_mapper; +void init_fd_mapper(struct fd_mapper *x); +void exit_fd_mapper(struct fd_mapper *x); +void fd_mapper_set(struct fd_mapper *x, FD fd, void *data); +void *fd_mapper_get(struct fd_mapper *x, FD fd); +struct fd_mapper_data; +struct fd_mapper; +void init_fd_mapper(struct fd_mapper *x); +void exit_fd_mapper(struct fd_mapper *x); +void fd_mapper_set(struct fd_mapper *x, FD fd, void *data); +void *fd_mapper_get(struct fd_mapper *x, FD fd); +struct fd_data_hash; +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); /* Prototypes end here */ #undef SOCKFUN1 @@ -101,6 +130,7 @@ FD fd_dup2(FD from, FD to); #define fd_shutdown_write SD_SEND #define fd_shutdown_both SD_BOTH +#define FD_PIPE -5 #define FD_SOCKET -4 #define FD_CONSOLE -3 #define FD_FILE -2 @@ -173,11 +203,13 @@ typedef int FD; #define fd_TRUNC O_TRUNC #define fd_EXCL O_EXCL +#define fd_query_properties(X,Y) ( fd_INTERPROCESSABLE | (Y)) #define fd_open open #define fd_close close #define fd_read read #define fd_write write #define fd_ioctl ioctl +#define fd_pipe pipe #define fd_socket socket #define fd_bind bind @@ -198,6 +230,7 @@ typedef int FD; #define fd_listen listen #define fd_select select +#define fd_socketpair socketpair #define fd_fd_set fd_set #define fd_FD_CLR FD_CLR @@ -222,6 +255,11 @@ typedef struct my_fd_set_s #define fd_copy_my_fd_set_to_fd_set(TO,FROM,max) \ MEMCPY((TO),&(FROM)->tmp,sizeof(*(TO))) +#define FILE_CAPABILITIES (fd_INTERPROCESSABLE) +#define PIPE_CAPABILITIES (fd_INTERPROCESSABLE | fd_BUFFERED) +#define UNIX_SOCKET_CAPABILITIES (fd_INTERPROCESSABLE | fd_BIDIRECTIONAL | fd_CAN_NONBLOCK) +#define SOCKET_CAPABILITIES (fd_INTERPROCESSABLE | fd_BIDIRECTIONAL | fd_CAN_NONBLOCK | fd_CAN_SHUTDOWN) + #endif #endif diff --git a/src/modules/files/configure.in b/src/modules/files/configure.in index 315010b15d9455c6885d83d67bbd5165c534eba4..59a01916dd71534324beaa6e8ccf38c8f7097622 100644 --- a/src/modules/files/configure.in +++ b/src/modules/files/configure.in @@ -11,7 +11,7 @@ AC_HEADER_DIRENT AC_CHECK_LIB(bind, __inet_ntoa) AC_CHECK_LIB(socket, socket) -AC_HAVE_FUNCS(getwd perror readdir_r statvfs statfs ustat lstat) +AC_HAVE_FUNCS(getwd perror readdir_r statvfs statfs ustat lstat socketpair) AC_MSG_CHECKING(if mkdir takes 1 or 2 arguments) AC_CACHE_VAL(pike_cv_func_mkdir_args,[ @@ -465,7 +465,7 @@ int main() AC_MSG_RESULT($pike_cv_select_on_unix_sockets) if test x$pike_cv_select_on_unix_sockets = xyes ; then - AC_DEFINE(HAVE_SOCKETPAIR) + AC_DEFINE(UNIX_SOCKETS_WORKS_WITH_SHUTDOWN) fi diff --git a/src/modules/files/file.c b/src/modules/files/file.c index 209693236553c90f10534f879ed50387597e6b1e..56e00e1e1ffd6b200866cab797dd2da0e184b52d 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.69 1998/01/25 08:28:00 hubbe Exp $"); +RCSID("$Id: file.c,v 1.70 1998/01/28 00:33:15 hubbe Exp $"); #include "fdlib.h" #include "interpret.h" #include "svalue.h" @@ -559,6 +559,14 @@ static void file_close(INT32 args) flags=FILE_READ | FILE_WRITE; } + if((files[FD].open_mode & ~flags & (FILE_READ|FILE_WRITE)) && flags) + { + if(!(files[FD].open_mode & fd_CAN_SHUTDOWN)) + { + error("Cannot close one direction on this file.\n"); + } + } + if(do_close(FD,flags)) FD=-1; pop_n_elems(args); @@ -618,7 +626,8 @@ static void file_open(INT32 args) } else { - init_fd(fd,flags); + + init_fd(fd,flags | fd_query_properties(fd, FILE_CAPABILITIES)); FD=fd; ERRNO = 0; set_close_on_exec(fd,1); @@ -813,6 +822,9 @@ static void file_set_nonblocking(INT32 args) { if(FD < 0) error("File not open.\n"); + if(!(files[FD].open_mode & fd_CAN_NONBLOCK)) + error("That file does not support nonblocking operation.\n"); + switch(args) { default: pop_n_elems(args-3); @@ -828,6 +840,9 @@ static void file_set_nonblocking(INT32 args) static void file_set_blocking(INT32 args) { + if(!(files[FD].open_mode & fd_CAN_NONBLOCK)) + error("That file does not support nonblocking operation.\n"); + free_svalue(& THIS->read_callback); THIS->read_callback.type=T_INT; THIS->read_callback.u.integer=0; @@ -921,11 +936,11 @@ static void file_query_close_callback(INT32 args) assign_svalue_no_free(sp++,& THIS->close_callback); } -struct object *file_make_object_from_fd(int fd, int mode) +struct object *file_make_object_from_fd(int fd, int mode, int guess) { struct object *o; - init_fd(fd, mode); + init_fd(fd, mode | fd_query_properties(fd, guess)); o=clone_object(file_program,0); ((struct file_struct *)(o->storage))->fd=fd; ((struct file_struct *)(o->storage))->my_errno=0; @@ -977,8 +992,6 @@ static void file_set_buffer(INT32 args) } -#ifndef HAVE_SOCKETPAIR - /* No socketpair() ? * No AF_UNIX sockets ? * No hope ? @@ -994,7 +1007,6 @@ static void file_set_buffer(INT32 args) * collide with any libs or headers. Also useful when testing * this code on a system that _has_ socketpair... */ -#define socketpair socketpair_ultra /* Protected since errno may expand to a function call. */ #ifndef errno @@ -1005,7 +1017,7 @@ int my_socketpair(int family, int type, int protocol, int sv[2]) static int fd=-1; static struct sockaddr_in my_addr; struct sockaddr_in addr,addr2; - int len; + int len,retries=0; MEMSET((char *)&addr,0,sizeof(struct sockaddr_in)); @@ -1056,6 +1068,8 @@ int my_socketpair(int family, int type, int protocol, int sv[2]) return -1; } + set_nonblocking(fd,1); + my_addr.sin_addr.s_addr=inet_addr("127.0.0.1"); } @@ -1064,27 +1078,31 @@ int my_socketpair(int family, int type, int protocol, int sv[2]) /* set_nonblocking(sv[1],1); */ +retry_connect: + retries++; if(fd_connect(sv[1], (struct sockaddr *)&my_addr, sizeof(addr)) < 0) { - int tmp2; - for(tmp2=0;tmp2<20;tmp2++) + fprintf(stderr,"errno=%d (%d)\n",errno,EWOULDBLOCK); + if(errno != EWOULDBLOCK) { - int tmp; - len=sizeof(addr); - tmp=fd_accept(fd,(struct sockaddr *)&addr,&len); - - if(tmp!=-1) fd_close(tmp); - if(fd_connect(sv[1], (struct sockaddr *)&my_addr, sizeof(my_addr))>=0) - break; + int tmp2; + for(tmp2=0;tmp2<20;tmp2++) + { + int tmp; + len=sizeof(addr); + tmp=fd_accept(fd,(struct sockaddr *)&addr,&len); + + if(tmp!=-1) + fd_close(tmp); + else + break; + } + if(retries > 20) return -1; + goto retry_connect; } - if(tmp2>=20) - return -1; } - len=sizeof(addr); - if(fd_getsockname(sv[1],(struct sockaddr *)&addr2,&len) < 0) return -1; - /* Accept connection * Make sure this connection was our OWN connection, * otherwise some wizeguy could interfere with our @@ -1095,9 +1113,11 @@ int my_socketpair(int family, int type, int protocol, int sv[2]) do { len=sizeof(addr); + retry_accept: sv[0]=fd_accept(fd,(struct sockaddr *)&addr,&len); if(sv[0] < 0) { + if(errno==EINTR) goto retry_accept; fd_close(sv[1]); return -1; } @@ -1105,17 +1125,18 @@ int my_socketpair(int family, int type, int protocol, int sv[2]) /* We do not trust accept */ len=sizeof(addr); if(fd_getpeername(sv[0], (struct sockaddr *)&addr,&len)) return -1; + len=sizeof(addr); + if(fd_getsockname(sv[1],(struct sockaddr *)&addr2,&len) < 0) return -1; }while(len < (int)sizeof(addr) || addr2.sin_addr.s_addr != addr.sin_addr.s_addr || addr2.sin_port != addr.sin_port); -/* set_nonblocking(sv[1],0); */ - +/* set_nonblocking(sv[1],0); */ return 0; } -int socketpair(int family, int type, int protocol, int sv[2]) +int socketpair_ultra(int family, int type, int protocol, int sv[2]) { int retries=0; @@ -1138,18 +1159,59 @@ int socketpair(int family, int type, int protocol, int sv[2]) } } - +#ifndef HAVE_SOCKETPAIR +#define socketpair socketpair_ultra #endif static void file_pipe(INT32 args) { int inout[2],i; + + int type=fd_CAN_NONBLOCK | fd_BIDIRECTIONAL; + + check_all_args("file->pipe",args, BIT_INT | BIT_VOID, 0); + if(args) type = sp[-args].u.integer;; + do_close(FD,FILE_READ | FILE_WRITE); FD=-1; pop_n_elems(args); ERRNO=0; - i=socketpair(AF_UNIX, SOCK_STREAM, 0, &inout[0]); + do + { +#ifdef PIPE_CAPABILITIES + if(!(type & ~(PIPE_CAPABILITIES))) + { + i=fd_pipe(&inout[0]); + type=PIPE_CAPABILITIES; + break; + } +#endif + +#ifdef UNIX_SOCKETS_WORK_WITH_SHUTDOWN +#undef UNIX_SOCKET_CAPABILITIES +#define UNIX_SOCKET_CAPABILITIES (fd_INTERPROCESSABLE | fd_BIDIRECTIONAL | fd_CAN_NONBLOCK | fd_CAN_SHUTDOWN) +#endif + +#if defined(HAVE_SOCKETPAIR) + if(!(type & ~(UNIX_SOCKET_CAPABILITIES))) + { + i=fd_socketpair(AF_UNIX, SOCK_STREAM, 0, &inout[0]); + type=UNIX_SOCKET_CAPABILITIES; + break; + } +#endif + + if(!(type & ~(SOCKET_CAPABILITIES))) + { + i=socketpair_ultra(AF_UNIX, SOCK_STREAM, 0, &inout[0]); + type=SOCKET_CAPABILITIES; + break; + } + + error("Cannot create a pipe patching those parameters.\n"); + }while(0); + if(i<0) { ERRNO=errno; @@ -1165,18 +1227,18 @@ static void file_pipe(INT32 args) } else { - init_fd(inout[0],FILE_READ | FILE_WRITE); - + init_fd(inout[0],FILE_READ | (type&fd_BIDIRECTIONAL?FILE_WRITE:0) | + fd_query_properties(inout[0], type)); + my_set_close_on_exec(inout[0],1); my_set_close_on_exec(inout[1],1); FD=inout[0]; - + ERRNO=0; - push_object(file_make_object_from_fd(inout[1],FILE_READ | FILE_WRITE)); + push_object(file_make_object_from_fd(inout[1], (type&fd_BIDIRECTIONAL?FILE_READ:0)| FILE_WRITE,type)); } } - static void init_file_struct(struct object *o) { FD=-1; @@ -1365,7 +1427,7 @@ static void file_open_socket(INT32 args) } } - init_fd(fd, FILE_READ | FILE_WRITE); + init_fd(fd, FILE_READ | FILE_WRITE | fd_query_properties(fd, SOCKET_CAPABILITIES)); my_set_close_on_exec(fd,1); FD = fd; ERRNO=0; @@ -1604,9 +1666,9 @@ void pike_module_init(void) files[e].refs=0; } - init_fd(0, FILE_READ); - init_fd(1, FILE_WRITE); - init_fd(2, FILE_WRITE); + init_fd(0, FILE_READ | fd_query_properties(0,fd_CAN_NONBLOCK)); + init_fd(1, FILE_WRITE | fd_query_properties(1,fd_CAN_NONBLOCK)); + init_fd(2, FILE_WRITE | fd_query_properties(2,fd_CAN_NONBLOCK)); init_files_efuns(); #if 0 @@ -1660,9 +1722,15 @@ void pike_module_init(void) set_gc_mark_callback(gc_mark_file_struct); file_program=end_program(); - add_program_constant("file",file_program,0); + add_program_constant("File",file_program,0); port_setup_program(); + + add_integer_constant("PROP_IPC",fd_INTERPROCESSABLE,0); + add_integer_constant("PROP_NONBLOCK",fd_CAN_NONBLOCK,0); + add_integer_constant("PROP_SHUTDOWN",fd_CAN_SHUTDOWN,0); + add_integer_constant("PROP_BUFFERED",fd_BUFFERED,0); + add_integer_constant("PROP_BIDIRECTIONAL",fd_BIDIRECTIONAL,0); add_gc_callback(mark_ids, 0, 0); } diff --git a/src/modules/files/file.h b/src/modules/files/file.h index e1856e6881406eb6f77a115847350e00dcc98557..a556e2c9c4e0a84637981a22405f565b573671fa 100644 --- a/src/modules/files/file.h +++ b/src/modules/files/file.h @@ -39,20 +39,23 @@ extern void get_inet_addr(struct sockaddr_in *addr,char *name); struct file_struct; void my_set_close_on_exec(int fd, int to); void do_set_close_on_exec(void); -struct object *file_make_object_from_fd(int fd, int mode); +struct object *file_make_object_from_fd(int fd, int mode, int guess); +int my_socketpair(int family, int type, int protocol, int sv[2]); int socketpair(int family, int type, int protocol, int sv[2]); -void exit_files(void); +void pike_module_exit(void); void mark_ids(struct callback *foo, void *bar, void *gazonk); -void init_files_programs(void); +void pike_module_init(void); +int pike_make_pipe(int *fds); /* Prototypes end here */ -#define FILE_READ 1 -#define FILE_WRITE 2 -#define FILE_APPEND 4 -#define FILE_CREATE 8 -#define FILE_TRUNC 16 -#define FILE_EXCLUSIVE 32 -#define FILE_NONBLOCKING 64 -#define FILE_SET_CLOSE_ON_EXEC 128 +#define FILE_READ 0x1000 +#define FILE_WRITE 0x2000 +#define FILE_APPEND 0x4000 +#define FILE_CREATE 0x8000 +#define FILE_TRUNC 0x0100 +#define FILE_EXCLUSIVE 0x0200 +#define FILE_NONBLOCKING 0x0400 +#define FILE_SET_CLOSE_ON_EXEC 0x0800 + #endif diff --git a/src/modules/files/socket.c b/src/modules/files/socket.c index 1f89819ea4d78e12ff6ca32b88619ee5d1e04066..cb75f7edc270d8670a090dfdc0922a5c3b149d9f 100644 --- a/src/modules/files/socket.c +++ b/src/modules/files/socket.c @@ -333,7 +333,7 @@ static void port_accept(INT32 args) } my_set_close_on_exec(fd,1); - o=file_make_object_from_fd(fd,FILE_READ | FILE_WRITE); + o=file_make_object_from_fd(fd,FILE_READ | FILE_WRITE, SOCKET_CAPABILITIES); pop_n_elems(args); push_object(o); @@ -408,6 +408,6 @@ void port_setup_program(void) set_init_callback(init_port_struct); set_exit_callback(exit_port_struct); - end_class("port",0); + end_class("Port",0); } diff --git a/src/modules/files/socktest.pike b/src/modules/files/socktest.pike index 9b65cb5db27d93921bccc16a0dc746636fb9d8b7..47235b6290ab2f728c2485e1cc7b190b1ce7d083 100755 --- a/src/modules/files/socktest.pike +++ b/src/modules/files/socktest.pike @@ -1,6 +1,6 @@ #!/usr/local/bin/pike -/* $Id: socktest.pike,v 1.7 1998/01/25 08:28:01 hubbe Exp $ */ +/* $Id: socktest.pike,v 1.8 1998/01/28 00:33:17 hubbe Exp $ */ import Stdio; import String; @@ -176,7 +176,9 @@ object *spair(int type) exit(1); } }else{ - sock2=sock1->pipe(); + sock2=sock1->pipe(Stdio.PROP_BIDIRECTIONAL | + Stdio.PROP_NONBLOCK | + Stdio.PROP_SHUTDOWN); if(!sock2) { werror("File->pipe() failed 0\n"); diff --git a/src/modules/files/testsuite.in b/src/modules/files/testsuite.in index ad77b2b7c3096119a58fdd5f4391b21f63674f03..2a238037ad954b400bb698c80ba6075278f32c72 100644 --- a/src/modules/files/testsuite.in +++ b/src/modules/files/testsuite.in @@ -92,7 +92,6 @@ test_true(arrayp(get_dir("."))) // - cd // - getcwd test_true(stringp(getcwd())) -test_eq('/',getcwd()[0]) // strerror cond([[all_constants()->strerror]], diff --git a/src/program.c b/src/program.c index 4a101fc72bddae14bd6fde770203023a295cff33..e1821cf52d0e82f57486029dea5012b249b36397 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.57 1998/01/27 20:02:15 hubbe Exp $"); +RCSID("$Id: program.c,v 1.58 1998/01/28 00:31:17 hubbe Exp $"); #include "program.h" #include "object.h" #include "dynamic_buffer.h" @@ -914,6 +914,12 @@ void low_inherit(struct program *p, return; } + if(!(p->flags & (PROGRAM_FINISHED | PROGRAM_PASS_1_DONE))) + { + yyerror("Cannot inherit program which is not fully compiled yet."); + return; + } + inherit_offset = new_program->num_inherits; storage_offset=new_program->storage_needed; @@ -2154,6 +2160,16 @@ struct program *program_from_svalue(struct svalue *s) { switch(s->type) { + case T_OBJECT: + { + struct program *p; + push_svalue(s); + f_object_program(1); + p=program_from_svalue(sp-1); + pop_stack(); + return p; /* We trust that there is a reference somewhere... */ + } + case T_FUNCTION: return program_from_function(s); case T_PROGRAM: