From 87dc4ff92fac7f4f74339180735e2a1132c63fb6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 3 Feb 1999 03:18:38 +0000 Subject: Fixed bug where cli->timeout was in milliseconds, but open_sockets_out was in seconds. This meant that PDC -> BDC failover took so long it essentiually didn't happen. include/client.h: Added explicit comment that cli->timeout should be milliseconds. include/local.h: Changed LONG_CONNECT_TIMEOUT & SHORT_CONNECT_TIMEOUT to be milliseconds. lib/smbrun.c: Tidied up fork failure catching. lib/util_sock.c: Ensured timeout treated as milliseconds. libsmb/clientgen.c: Added comment. rpc_server/srv_pipe_hnd.c: Luke's changes. smbd/chgpasswd.c: Paranoia code for EINTR around sys_waitpid. Jeremy. --- source/include/client.h | 2 +- source/include/local.h | 6 +++--- source/lib/smbrun.c | 20 ++++++++++++++++++-- source/lib/util_sock.c | 4 ++-- source/libsmb/clientgen.c | 2 +- source/rpc_server/srv_pipe_hnd.c | 35 +++++++++++++++++++---------------- source/smbd/chgpasswd.c | 9 ++++++++- 7 files changed, 52 insertions(+), 26 deletions(-) diff --git a/source/include/client.h b/source/include/client.h index f5226e32e8e..417db1f2575 100644 --- a/source/include/client.h +++ b/source/include/client.h @@ -111,7 +111,7 @@ struct cli_state { uint32 servertime; int readbraw_supported; int writebraw_supported; - int timeout; + int timeout; /* in milliseconds. */ int max_xmit; int max_mux; char *outbuf; diff --git a/source/include/local.h b/source/include/local.h index f8c9770a158..92288a20b80 100644 --- a/source/include/local.h +++ b/source/include/local.h @@ -152,9 +152,9 @@ /* shall we support browse requests via a FIFO to nmbd? */ #define ENABLE_FIFO 1 -/* how long to wait for a socket connect to happen */ -#define LONG_CONNECT_TIMEOUT 30 -#define SHORT_CONNECT_TIMEOUT 5 +/* how long (in miliseconds) to wait for a socket connect to happen */ +#define LONG_CONNECT_TIMEOUT 30000 +#define SHORT_CONNECT_TIMEOUT 5000 /* default socket options. Dave Miller thinks we should default to TCP_NODELAY given the socket IO pattern that Samba uses*/ diff --git a/source/lib/smbrun.c b/source/lib/smbrun.c index f8eb9134aed..7162b9266ae 100644 --- a/source/lib/smbrun.c +++ b/source/lib/smbrun.c @@ -116,10 +116,26 @@ int smbrun(char *cmd,char *outfile,BOOL shared) /* in this newer method we will exec /bin/sh with the correct arguments, after first setting stdout to point at the file */ - if ((pid=fork())) { + if ((pid=fork()) < 0) { + DEBUG(0,("smbrun: fork failed with error %s\n", strerror(errno) )); + return errno; + } + + if (pid) { + /* + * Parent. + */ int status=0; + pid_t wpid; + /* the parent just waits for the child to exit */ - if (sys_waitpid(pid,&status,0) != pid) { + while((wpid = sys_waitpid(pid,&status,0)) < 0) { + if(errno == EINTR) { + errno = 0; + continue; + } + } + if (wpid != pid) { DEBUG(2,("waitpid(%d) : %s\n",pid,strerror(errno))); return -1; } diff --git a/source/lib/util_sock.c b/source/lib/util_sock.c index a05243d1689..6d395659c92 100644 --- a/source/lib/util_sock.c +++ b/source/lib/util_sock.c @@ -679,14 +679,14 @@ int open_socket_in(int type, int port, int dlevel,uint32 socket_addr) /**************************************************************************** - create an outgoing socket + create an outgoing socket. timeout is in milliseconds. **************************************************************************/ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) { struct sockaddr_in sock_out; int res,ret; int connect_loop = 250; /* 250 milliseconds */ - int loops = (timeout * 1000) / connect_loop; + int loops = (timeout) / connect_loop; /* create a socket to write to */ res = socket(PF_INET, type, 0); diff --git a/source/libsmb/clientgen.c b/source/libsmb/clientgen.c index 92a90d2ccf8..636bb6db0f7 100644 --- a/source/libsmb/clientgen.c +++ b/source/libsmb/clientgen.c @@ -2424,7 +2424,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->mid = 1; cli->vuid = UID_FIELD_INVALID; cli->protocol = PROTOCOL_NT1; - cli->timeout = 20000; + cli->timeout = 20000; /* Timeout is in milliseconds. */ cli->bufsize = CLI_BUFFER_SIZE+4; cli->max_xmit = cli->bufsize; cli->outbuf = (char *)malloc(cli->bufsize); diff --git a/source/rpc_server/srv_pipe_hnd.c b/source/rpc_server/srv_pipe_hnd.c index e7d996995d3..ca5dde18d25 100644 --- a/source/rpc_server/srv_pipe_hnd.c +++ b/source/rpc_server/srv_pipe_hnd.c @@ -202,10 +202,11 @@ ssize_t write_pipe(pipes_struct *p, char *data, size_t n) int read_pipe(pipes_struct *p, char *data, uint32 pos, int n) { int num = 0; - int len = 0; + int pdu_len = 0; uint32 hdr_num = 0; - int data_hdr_pos; - int data_pos; + int pdu_data_sent; /* amount of current pdu already sent */ + int data_pos; /* entire rpc data sent - no headers, no auth verifiers */ + int this_pdu_data_pos; DEBUG(6,("read_pipe: %x", p->pnum)); @@ -231,33 +232,35 @@ int read_pipe(pipes_struct *p, char *data, uint32 pos, int n) p, p->file_offset, n)); /* the read request starts from where the SMBtrans2 left off. */ - data_hdr_pos = p->file_offset - p->prev_pdu_file_offset; - data_pos = data_hdr_pos - p->hdr_offsets; + data_pos = p->file_offset - p->hdr_offsets; + this_pdu_data_pos = data_pos - p->prev_pdu_file_offset; + pdu_data_sent = p->file_offset - p->prev_pdu_file_offset; if (!IS_BITS_SET_ALL(p->hdr.flags, RPC_FLG_LAST)) { /* intermediate fragment - possibility of another header */ - DEBUG(5,("read_pipe: frag_len: %d data_pos: %d data_hdr_pos: %d\n", - p->hdr.frag_len, data_pos, data_hdr_pos)); + DEBUG(5,("read_pipe: frag_len: %d data_pos: %d pdu_data_sent: %d\n", + p->hdr.frag_len, data_pos, pdu_data_sent)); - if (data_hdr_pos == 0) + if (pdu_data_sent == 0) { DEBUG(6,("read_pipe: next fragment header\n")); /* this is subtracted from the total data bytes, later */ hdr_num = 0x18; p->hdr_offsets += 0x18; + data_pos -= 0x18; /* create and copy in a new header. */ - create_rpc_reply(p, p->file_offset - p->hdr_offsets, p->rdata.offset); + create_rpc_reply(p, data_pos, p->rdata.offset); } } - len = mem_buf_len(p->rhdr.data); - num = len - (int)data_pos; + pdu_len = mem_buf_len(p->rhdr.data); + num = pdu_len - (int)this_pdu_data_pos; - DEBUG(6,("read_pipe: len: %d num: %d n: %d\n", len, num, n)); + DEBUG(6,("read_pipe: pdu_len: %d num: %d n: %d\n", pdu_len, num, n)); if (num > n) num = n; if (num <= 0) @@ -271,17 +274,17 @@ int read_pipe(pipes_struct *p, char *data, uint32 pos, int n) DEBUG(5,("read_pipe: warning - data read only part of a header\n")); } - mem_buf_copy(data, p->rhdr.data, data_pos, num); + mem_buf_copy(data, p->rhdr.data, pdu_data_sent, num); - data_pos += num; - data_hdr_pos += num; p->file_offset += num; + pdu_data_sent += num; if (hdr_num == 0x18 && num == 0x18) { DEBUG(6,("read_pipe: just header read\n")); } - else if (data_hdr_pos == p->hdr.frag_len) + + if (pdu_data_sent == p->hdr.frag_len) { DEBUG(6,("read_pipe: next fragment expected\n")); p->prev_pdu_file_offset = p->file_offset; diff --git a/source/smbd/chgpasswd.c b/source/smbd/chgpasswd.c index ebbc79c4a10..bdc7cb11592 100644 --- a/source/smbd/chgpasswd.c +++ b/source/smbd/chgpasswd.c @@ -318,7 +318,14 @@ static BOOL chat_with_program(char *passwordprogram,char *name,char *chatsequenc kill(pid, SIGKILL); /* be sure to end this process */ } - if ((wpid = sys_waitpid(pid, &wstat, 0)) < 0) { + while((wpid = sys_waitpid(pid, &wstat, 0)) < 0) { + if(errno == EINTR) { + errno = 0; + continue; + } + } + + if (wpid < 0) { DEBUG(3,("The process is no longer waiting!\n\n")); close(master); CatchChild(); -- cgit