added a wrapper for fork()
authorAndrew Tridgell <tridge@samba.org>
Tue, 6 Oct 1998 12:23:37 +0000 (12:23 +0000)
committerAndrew Tridgell <tridge@samba.org>
Tue, 6 Oct 1998 12:23:37 +0000 (12:23 +0000)
in a fork we have to close all server connections otherwise we can end
up with two processes writing to the same socket.

source/configure
source/configure.in
source/include/config.h.in
source/smbwrapper/realcalls.h
source/smbwrapper/smbw.c
source/smbwrapper/smbw_dir.c
source/smbwrapper/wrapped.c

index a807413bb633caa2c013366e73ce21c3328d160f..938d6c55c7d7618af19293ed1a1b94c600969beb 100755 (executable)
@@ -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
index c9f3ff6150eb777f234fedef37cf18ff18b13a42..0815343ecde1f43c3da29c323e20df559c752c51 100644 (file)
@@ -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)
index 930832a8bd5a1e997de002b66fbc335544f34282..92056f075af465c845ac949dd4e280a4c50885f0 100644 (file)
 /* 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
 
 /* 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
 
index 338e1950874d165fcc6bff0b2e05526d6dc0e7f7..65431bf53f73fddf559b00ab7903376d98a82d20 100644 (file)
 #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
index e5359360c3db4e37f18174f6ebe2bc96da6287ea..6096f096a305fa22d0f4ef6aa159b2d1b5f67e7d 100644 (file)
@@ -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;
+}
index a932c102dc3ca4cccaa93c168ed967d18eaca19d..2c1b7ef9ecb4a1951050cc4cedc80cbbc5e91edd 100644 (file)
@@ -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);
 }
+
index bda0ed1abe1b301f7119611379e8783aea769f71..10b22b35dd4438b9c55c9957a1c8fb788e958023 100644 (file)
@@ -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();
+}