summaryrefslogtreecommitdiffstats
path: root/source3
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
parent4fe9c5b65614d048c053989ab3d1e97b1bbcfa2b (diff)
downloadsamba-fff618aeb4142773ff388ac9b52d127a510c6690.tar.gz
samba-fff618aeb4142773ff388ac9b52d127a510c6690.tar.xz
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')
-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 a807413bb63..938d6c55c7d 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 c9f3ff6150e..0815343ecde 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 930832a8bd5..92056f075af 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 338e1950874..65431bf53f7 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 e5359360c3d..6096f096a30 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 a932c102dc3..2c1b7ef9ecb 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 bda0ed1abe1..10b22b35dd4 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();
+}