summaryrefslogtreecommitdiff
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
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)
-rwxr-xr-xsource3/configure2
-rw-r--r--source3/configure.in2
-rw-r--r--source3/include/config.h.in6
-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
7 files changed, 91 insertions, 2 deletions
diff --git a/source3/configure b/source3/configure
index a807413bb6..938d6c55c7 100755
--- a/source3/configure
+++ b/source3/configure
@@ -4401,7 +4401,7 @@ else
fi
done
-for ac_func in _write __write
+for ac_func in _write __write _fork __fork
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:4408: checking for $ac_func" >&5
diff --git a/source3/configure.in b/source3/configure.in
index c9f3ff6150..0815343ecd 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -189,7 +189,7 @@ AC_CHECK_FUNCS(_stat _lstat _fstat __stat __lstat __fstat)
AC_CHECK_FUNCS(_acl __acl _facl __facl _open __open _chdir __chdir)
AC_CHECK_FUNCS(_close __close _fchdir __fchdir _fcntl __fcntl)
AC_CHECK_FUNCS(_getdents __getdents _lseek __lseek _read __read)
-AC_CHECK_FUNCS(_write __write)
+AC_CHECK_FUNCS(_write __write _fork __fork)
AC_CHECK_FUNCS(_stat64 __stat64 _fstat64 __fstat64 _lstat64 __lstat64)
AC_CHECK_FUNCS(llseek _llseek __llseek readdir64 _readdir64 __readdir64)
AC_CHECK_FUNCS(pread _pread __pread pread64 _pread64 __pread64)
diff --git a/source3/include/config.h.in b/source3/include/config.h.in
index 930832a8bd..92056f075a 100644
--- a/source3/include/config.h.in
+++ b/source3/include/config.h.in
@@ -165,6 +165,9 @@
/* Define if you have the __fcntl function. */
#undef HAVE___FCNTL
+/* Define if you have the __fork function. */
+#undef HAVE___FORK
+
/* Define if you have the __fstat function. */
#undef HAVE___FSTAT
@@ -270,6 +273,9 @@
/* Define if you have the _fcntl function. */
#undef HAVE__FCNTL
+/* Define if you have the _fork function. */
+#undef HAVE__FORK
+
/* Define if you have the _fstat function. */
#undef HAVE__FSTAT
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();
+}