From c657d098ad1097922fbf6393e3f9eb91bf81f0aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net> Date: Wed, 29 Jan 1997 13:45:27 -0800 Subject: [PATCH] closed on exec now updated only at fork() or exec(), write() on nonblocking files optimized Rev: src/modules/files/file.c:1.27 Rev: src/modules/files/file.h:1.3 --- src/modules/files/file.c | 98 ++++++++++++++++++++++++++++------------ src/modules/files/file.h | 5 ++ 2 files changed, 75 insertions(+), 28 deletions(-) diff --git a/src/modules/files/file.c b/src/modules/files/file.c index 7de6a8ad45..2c56773663 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.26 1997/01/29 20:57:29 per Exp $"); +RCSID("$Id: file.c,v 1.27 1997/01/29 21:45:27 hubbe Exp $"); #include "types.h" #include "interpret.h" #include "svalue.h" @@ -164,6 +164,32 @@ static int close_fd(int fd) return 0; } +void my_set_close_on_exec(int fd, int to) +{ + if(to) + { + files[fd].open_mode |= FILE_SET_CLOSE_ON_EXEC; + }else{ + if(files[fd].open_mode & FILE_SET_CLOSE_ON_EXEC) + files[fd].open_mode &=~ FILE_SET_CLOSE_ON_EXEC; + else + set_close_on_exec(fd, 0); + } +} + +void do_set_close_on_exec() +{ + int e; + for(e=0;e<MAX_OPEN_FILEDESCRIPTORS;e++) + { + if(files[e].open_mode & FILE_SET_CLOSE_ON_EXEC) + { + set_close_on_exec(e, 1); + files[e].open_mode &=~ FILE_SET_CLOSE_ON_EXEC; + } + } +} + /* Parse "rw" to internal flags */ static int parse(char *a) { @@ -405,18 +431,8 @@ static void file_write(INT32 args) written=0; str=sp[-args].u.string; -/* while(written < str->len) Not really. The only thing this does is: - - write(24, " H e d b o r < / a > < /".., 534712) = 7300 - write(24, " f = / m l i s t . l p c".., 527412) Err#11 EAGAIN - - etc. - - The 'write' system call in blocking mode is quite atomous, unless a - signal is received. This case (signals) is handled below. /Per - - */ - do { + while(written < str->len) + { int fd=FD; THREADS_ALLOW(); i=write(fd, str->str + written, str->len - written); @@ -432,13 +448,18 @@ static void file_write(INT32 args) push_int(-1); return; - case EINTR: continue; /* Got a signal, Retry... /Per */ + case EINTR: continue; case EWOULDBLOCK: break; } + break; + }else{ + written+=i; + + /* Avoid extra write() */ + if(THIS->open_mode & FILE_NONBLOCKING) + break; } - written=i; - break; - } while(1); + } if(!IS_ZERO(& THIS->write_callback)) set_write_callback(FD, file_write_callback, 0); @@ -763,6 +784,7 @@ static void file_set_nonblocking(INT32 args) case 1: file_set_read_callback(1); } set_nonblocking(FD,1); + THIS->open_mode |= FILE_NONBLOCKING; } @@ -783,6 +805,7 @@ static void file_set_blocking(INT32 args) set_read_callback(FD, 0, 0); set_write_callback(FD, 0, 0); set_nonblocking(FD,0); + THIS->open_mode &=~ FILE_NONBLOCKING; } pop_n_elems(args); } @@ -790,15 +813,15 @@ static void file_set_blocking(INT32 args) static void file_set_close_on_exec(INT32 args) { if(args < 0) - error("Too few arguments to file->set_close_on_exit()\n"); + error("Too few arguments to file->set_close_on_exec()\n"); if(FD <0) error("File not open.\n"); if(IS_ZERO(sp-args)) { - set_close_on_exec(FD,0); + my_set_close_on_exec(FD,0); }else{ - set_close_on_exec(FD,1); + my_set_close_on_exec(FD,1); } pop_n_elems(args-1); } @@ -1036,8 +1059,8 @@ static void file_pipe(INT32 args) { init_fd(inout[0],FILE_READ | FILE_WRITE); - set_close_on_exec(inout[0],1); - set_close_on_exec(inout[1],1); + my_set_close_on_exec(inout[0],1); + my_set_close_on_exec(inout[1],1); FD=inout[0]; ERRNO=0; @@ -1137,7 +1160,7 @@ static void file_dup2(INT32 args) return; } ERRNO=0; - set_close_on_exec(fd, fd > 2); + my_set_close_on_exec(fd, fd > 2); files[fd].open_mode=files[FD].open_mode; assign_svalue_no_free(& files[fd].read_callback, & THIS->read_callback); @@ -1165,7 +1188,7 @@ static void file_dup2(INT32 args) static void file_open_socket(INT32 args) { - int fd,tmp; + int fd; do_close(FD, FILE_READ | FILE_WRITE); FD=-1; @@ -1185,10 +1208,8 @@ static void file_open_socket(INT32 args) return; } - tmp=1; - setsockopt(fd,SOL_SOCKET, SO_KEEPALIVE, (char *)&tmp, sizeof(tmp)); init_fd(fd, FILE_READ | FILE_WRITE); - set_close_on_exec(fd,1); + my_set_close_on_exec(fd,1); FD = fd; ERRNO=0; @@ -1196,6 +1217,22 @@ static void file_open_socket(INT32 args) push_int(1); } +static void file_set_keepalive(INT32 args) +{ + int tmp, i; + check_all_args("file->set_keepalive()",args, 1, T_INT); + tmp=sp[-args].u.integer; + i=setsockopt(FD,SOL_SOCKET, SO_KEEPALIVE, (char *)&tmp, sizeof(tmp)); + if(i) + { + ERRNO=errno; + }else{ + ERRNO=0; + } + pop_n_elems(args); + push_int(!i); +} + static void file_connect(INT32 args) { struct sockaddr_in addr; @@ -1210,7 +1247,12 @@ static void file_connect(INT32 args) error("Bad argument 2 to file->connect()\n"); if(FD < 0) - error("file->connect(): File not open for connect()\n"); + { + file_open_socket(0); + if(IS_ZERO(sp-1) || FD < 0) + error("file->connect(): Failed to open socket.\n"); + pop_stack(); + } get_inet_addr(&addr, sp[-args].u.string->str); diff --git a/src/modules/files/file.h b/src/modules/files/file.h index 4b871147b8..548c9e9a48 100644 --- a/src/modules/files/file.h +++ b/src/modules/files/file.h @@ -38,9 +38,12 @@ extern void get_inet_addr(struct sockaddr_in *addr,char *name); /* Prototypes begin here */ struct file_struct; +void my_set_close_on_exec(int fd, int to); +void do_set_close_on_exec(); struct object *file_make_object_from_fd(int fd, int mode); int socketpair(int family, int type, int protocol, int sv[2]); void exit_files(); +void mark_ids(struct callback *foo, void *bar, void *gazonk); void init_files_programs(); /* Prototypes end here */ @@ -50,5 +53,7 @@ void init_files_programs(); #define FILE_CREATE 8 #define FILE_TRUNC 16 #define FILE_EXCLUSIVE 32 +#define FILE_NONBLOCKING 64 +#define FILE_SET_CLOSE_ON_EXEC 128 #endif -- GitLab