void sync_browse_lists(struct work_record *work, char *name, int nm_type, struct in_addr ip, bool local, bool servers) { struct sync_record *s; static int counter; START_PROFILE(sync_browse_lists); /* Check we're not trying to sync with ourselves. This can happen if we are a domain *and* a local master browser. */ if (ismyip_v4(ip)) { done: END_PROFILE(sync_browse_lists); return; } s = SMB_MALLOC_P(struct sync_record); if (!s) goto done; ZERO_STRUCTP(s); unstrcpy(s->workgroup, work->work_group); unstrcpy(s->server, name); s->ip = ip; if (asprintf(&s->fname, "%s/sync.%d", lp_lockdir(), counter++) < 0) { SAFE_FREE(s); goto done; } /* Safe to use as 0 means no size change. */ all_string_sub(s->fname,"//", "/", 0); DLIST_ADD(syncs, s); /* the parent forks and returns, leaving the child to do the actual sync and call END_PROFILE*/ CatchChild(); if ((s->pid = sys_fork())) return; BlockSignals( False, SIGTERM ); DEBUG(2,("Initiating browse sync for %s to %s(%s)\n", work->work_group, name, inet_ntoa(ip))); fp = x_fopen(s->fname,O_WRONLY|O_CREAT|O_TRUNC, 0644); if (!fp) { END_PROFILE(sync_browse_lists); _exit(1); } sync_child(name, nm_type, work->work_group, ip, local, servers, s->fname); x_fclose(fp); END_PROFILE(sync_browse_lists); _exit(0); }
/* * prb_child_create() - this routine instantiates and rendevous with the * target child process. This routine returns an opaque handle for the * childs /proc entry. */ prb_status_t prb_child_create(const char *cmdname, char * const *cmdargs, const char *loption, const char *libtnfprobe_path, char * const *envp, prb_proc_ctl_t **ret_val) { prb_status_t prbstat; pid_t childpid; char executable_name[PATH_MAX + 2]; extern char **environ; char * const * env_to_use; size_t loptlen, probepathlen; volatile shmem_msg_t *smp; /* initialize shmem communication buffer to cause child to wait */ prbstat = prb_shmem_init(&smp); if (prbstat) return (prbstat); /* fork to create the child process */ childpid = fork(); if (childpid == (pid_t) - 1) { DBG(perror("prb_child_create: fork failed")); return (prb_status_map(errno)); } if (childpid == 0) { char *oldenv; char *newenv; /* ---- CHILD PROCESS ---- */ DBG_TNF_PROBE_1(prb_child_create_1, "libtnfctl", "sunw%verbosity 1; sunw%debug 'child process created'", tnf_long, pid, getpid()); if (envp) { env_to_use = envp; goto ContChild; } /* append libtnfprobe.so to the LD_PRELOAD environment */ loptlen = (loption) ? strlen(loption) : 0; /* probepathlen has a "/" added in ("+ 1") */ probepathlen = (libtnfprobe_path) ? (strlen(libtnfprobe_path) + 1) : 0; oldenv = getenv(PRELOAD); if (oldenv) { newenv = (char *) malloc(strlen(PRELOAD) + 1 + /* "=" */ strlen(oldenv) + 1 + /* " " */ probepathlen + strlen(LIBPROBE) + 1 + /* " " */ loptlen + 1); /* NULL */ if (!newenv) goto ContChild; (void) strcpy(newenv, PRELOAD); (void) strcat(newenv, "="); (void) strcat(newenv, oldenv); (void) strcat(newenv, " "); if (probepathlen) { (void) strcat(newenv, libtnfprobe_path); (void) strcat(newenv, "/"); } (void) strcat(newenv, LIBPROBE); if (loptlen) { (void) strcat(newenv, " "); (void) strcat(newenv, loption); } } else { newenv = (char *) malloc(strlen(PRELOAD) + 1 + /* "=" */ probepathlen + strlen(LIBPROBE) + 1 + /* " " */ loptlen + 1); /* NULL */ if (!newenv) goto ContChild; (void) strcpy(newenv, PRELOAD); (void) strcat(newenv, "="); if (probepathlen) { (void) strcat(newenv, libtnfprobe_path); (void) strcat(newenv, "/"); } (void) strcat(newenv, LIBPROBE); if (loptlen) { (void) strcat(newenv, " "); (void) strcat(newenv, loption); } } (void) putenv((char *) newenv); env_to_use = environ; /* * We don't check the return value of putenv because the * desired libraries might already be in the target, even * if our effort to change the environment fails. We * should continue either way ... */ ContChild: /* wait until the parent releases us */ (void) prb_shmem_wait(smp); DBG_TNF_PROBE_1(prb_child_create_2, "libtnfctl", "sunw%verbosity 2; " "sunw%debug 'child process about to exec'", tnf_string, cmdname, cmdname); /* * make the child it's own process group. * This is so that signals delivered to parent are not * also delivered to child. */ (void) setpgrp(); prbstat = find_executable(cmdname, executable_name); if (prbstat) { DBG((void) fprintf(stderr, "prb_child_create: %s\n", prb_status_str(prbstat))); /* parent waits for exit */ _exit(1); } if (execve(executable_name, cmdargs, env_to_use) == -1) { DBG(perror("prb_child_create: exec failed")); _exit(1); } /* Never reached */ _exit(1); } /* ---- PARENT PROCESS ---- */ /* child is waiting for us */ prbstat = sync_child(childpid, smp, ret_val); if (prbstat) { return (prbstat); } return (PRB_STATUS_OK); }