diff options
Diffstat (limited to 'source3/smbwrapper')
-rw-r--r-- | source3/smbwrapper/realcalls.h | 8 | ||||
-rw-r--r-- | source3/smbwrapper/smbw.c | 69 | ||||
-rw-r--r-- | source3/smbwrapper/smbw_dir.c | 1 | ||||
-rw-r--r-- | source3/smbwrapper/wrapped.c | 5 |
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(); +} |