summaryrefslogtreecommitdiff
path: root/source3/smbwrapper
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>1998-10-06 12:23:37 +0000
committerAndrew Tridgell <tridge@samba.org>1998-10-06 12:23:37 +0000
commitfff618aeb4142773ff388ac9b52d127a510c6690 (patch)
tree72043a849d02ac89ee7dac20f8ae04830ea8832d /source3/smbwrapper
parent4fe9c5b65614d048c053989ab3d1e97b1bbcfa2b (diff)
downloadsamba-fff618aeb4142773ff388ac9b52d127a510c6690.tar.gz
samba-fff618aeb4142773ff388ac9b52d127a510c6690.tar.bz2
samba-fff618aeb4142773ff388ac9b52d127a510c6690.zip
added a wrapper for fork()
in a fork we have to close all server connections otherwise we can end up with two processes writing to the same socket. (This used to be commit b7ecbca3aff34ff06a445e5ee39efba48261b7e8)
Diffstat (limited to 'source3/smbwrapper')
-rw-r--r--source3/smbwrapper/realcalls.h8
-rw-r--r--source3/smbwrapper/smbw.c69
-rw-r--r--source3/smbwrapper/smbw_dir.c1
-rw-r--r--source3/smbwrapper/wrapped.c5
4 files changed, 83 insertions, 0 deletions
diff --git a/source3/smbwrapper/realcalls.h b/source3/smbwrapper/realcalls.h
index 338e195087..65431bf53f 100644
--- a/source3/smbwrapper/realcalls.h
+++ b/source3/smbwrapper/realcalls.h
@@ -51,6 +51,14 @@
#define NO_OPEN64_ALIAS
#endif
+#ifdef HAVE__FORK
+#define real_fork() (_fork())
+#elif HAVE___FORK
+#define real_fork() (__fork())
+#elif SYS_fork
+#define real_fork() (syscall(SYS_fork,()))
+#endif
+
#ifdef HAVE__OPENDIR
#define real_opendir(fn) ((DIR *)_opendir(fn))
#elif SYS_opendir
diff --git a/source3/smbwrapper/smbw.c b/source3/smbwrapper/smbw.c
index e5359360c3..6096f096a3 100644
--- a/source3/smbwrapper/smbw.c
+++ b/source3/smbwrapper/smbw.c
@@ -1229,3 +1229,72 @@ int smbw_dup2(int fd, int fd2)
return -1;
}
+
+/*****************************************************
+close a connection to a server
+*******************************************************/
+static void smbw_srv_close(struct smbw_server *srv)
+{
+ smbw_busy++;
+
+ cli_shutdown(&srv->cli);
+
+ free(srv->server_name);
+ free(srv->share_name);
+
+ DLIST_REMOVE(smbw_srvs, srv);
+
+ ZERO_STRUCTP(srv);
+
+ free(srv);
+
+ smbw_busy--;
+}
+
+/*****************************************************
+when we fork we have to close all connections and files
+in the child
+*******************************************************/
+int smbw_fork(void)
+{
+ pid_t child;
+ int p[2];
+ char c=0;
+
+ struct smbw_file *file, *next_file;
+ struct smbw_server *srv, *next_srv;
+
+ if (pipe(p)) return real_fork();
+
+ child = real_fork();
+
+ if (child) {
+ /* block the parent for a moment until the sockets are
+ closed */
+ close(p[1]);
+ read(p[0], &c, 1);
+ close(p[0]);
+ return child;
+ }
+
+ close(p[0]);
+
+ /* close all files */
+ for (file=smbw_files;file;file=next_file) {
+ next_file = file->next;
+ close(file->fd);
+ }
+
+ /* close all server connections */
+ for (srv=smbw_srvs;srv;srv=next_srv) {
+ next_srv = srv->next;
+ smbw_srv_close(srv);
+ }
+
+ /* unblock the parent */
+ write(p[1], &c, 1);
+ close(p[1]);
+
+ /* and continue in the child */
+ return 0;
+}
diff --git a/source3/smbwrapper/smbw_dir.c b/source3/smbwrapper/smbw_dir.c
index a932c102dc..2c1b7ef9ec 100644
--- a/source3/smbwrapper/smbw_dir.c
+++ b/source3/smbwrapper/smbw_dir.c
@@ -664,3 +664,4 @@ off_t smbw_telldir(DIR *dirp)
struct smbw_dir *d = (struct smbw_dir *)dirp;
return smbw_dir_lseek(d->fd,0,SEEK_CUR);
}
+
diff --git a/source3/smbwrapper/wrapped.c b/source3/smbwrapper/wrapped.c
index bda0ed1abe..10b22b35dd 100644
--- a/source3/smbwrapper/wrapped.c
+++ b/source3/smbwrapper/wrapped.c
@@ -908,3 +908,8 @@ static void dirent64_convert(struct dirent *d, struct dirent64 *d64)
return real_readdir64(dir);
}
#endif
+
+ int fork(void)
+{
+ return smbw_fork();
+}