예제 #1
0
static int rebalance2(struct shadow_spine *s, struct dm_btree_info *info,
		      struct dm_btree_value_type *vt, unsigned left_index)
{
	int r;
	struct btree_node *parent;
	struct child left, right;

	parent = dm_block_data(shadow_current(s));

	r = init_child(info, vt, parent, left_index, &left);
	if (r)
		return r;

	r = init_child(info, vt, parent, left_index + 1, &right);
	if (r) {
		exit_child(info, &left);
		return r;
	}

	__rebalance2(info, parent, &left, &right);

	r = exit_child(info, &left);
	if (r) {
		exit_child(info, &right);
		return r;
	}

	return exit_child(info, &right);
}
예제 #2
0
static int rebalance3(struct shadow_spine *s, struct dm_btree_info *info,
		      struct dm_btree_value_type *vt, unsigned left_index)
{
	int r;
	struct btree_node *parent = dm_block_data(shadow_current(s));
	struct child left, center, right;

	/*
	 * FIXME: fill out an array?
	 */
	r = init_child(info, vt, parent, left_index, &left);
	if (r)
		return r;

	r = init_child(info, vt, parent, left_index + 1, &center);
	if (r) {
		exit_child(info, &left);
		return r;
	}

	r = init_child(info, vt, parent, left_index + 2, &right);
	if (r) {
		exit_child(info, &left);
		exit_child(info, &center);
		return r;
	}

	__rebalance3(info, parent, &left, &center, &right);

	r = exit_child(info, &left);
	if (r) {
		exit_child(info, &center);
		exit_child(info, &right);
		return r;
	}

	r = exit_child(info, &center);
	if (r) {
		exit_child(info, &right);
		return r;
	}

	r = exit_child(info, &right);
	if (r)
		return r;

	return 0;
}
예제 #3
0
파일: tcp_main.c 프로젝트: OPSF/uClinux
/* starts the tcp processes */
int tcp_init_children()
{
	int r;
	int sockfd[2];
	int reader_fd[2]; /* for comm. with the tcp children read  */
	pid_t pid;
	
	
	/* create the tcp sock_info structures */
	/* copy the sockets --moved to main_loop*/
	
	/* fork children & create the socket pairs*/
	for(r=0; r<tcp_children_no; r++){
		if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd)<0){
			LOG(L_ERR, "ERROR: tcp_main: socketpair failed: %s\n",
					strerror(errno));
			goto error;
		}
		if (socketpair(AF_UNIX, SOCK_STREAM, 0, reader_fd)<0){
			LOG(L_ERR, "ERROR: tcp_main: socketpair failed: %s\n",
					strerror(errno));
			goto error;
		}
		
		process_no++;
		pid=fork();
		if (pid<0){
			LOG(L_ERR, "ERROR: tcp_main: fork failed: %s\n",
					strerror(errno));
			goto error;
		}else if (pid>0){
			/* parent */
			close(sockfd[1]);
			close(reader_fd[1]);
			tcp_children[r].pid=pid;
			tcp_children[r].proc_no=process_no;
			tcp_children[r].busy=0;
			tcp_children[r].n_reqs=0;
			tcp_children[r].unix_sock=reader_fd[0];
			pt[process_no].pid=pid;
			pt[process_no].unix_sock=sockfd[0];
			pt[process_no].idx=r;
			strncpy(pt[process_no].desc, "tcp receiver", MAX_PT_DESC);
		}else{
			/* child */
			close(sockfd[0]);
			unix_tcp_sock=sockfd[1];
			bind_address=0; /* force a SEGFAULT if someone uses a non-init.
							   bind address on tcp */
			if (init_child(r+children_no+1) < 0) {
				LOG(L_ERR, "init_children failed\n");
				goto error;
			}
			tcp_receive_loop(reader_fd[1]);
		}
	}
	return 0;
error:
	return -1;
}
예제 #4
0
/*
 * Control ops entry point:
 *
 * Requests handled completely:
 *      DDI_CTLOPS_INITCHILD
 *      DDI_CTLOPS_UNINITCHILD
 * All others are passed to the parent.
 */
static int
acpinex_ctlops(dev_info_t *dip, dev_info_t *rdip, ddi_ctl_enum_t op, void *arg,
    void *result)
{
	int rval = DDI_SUCCESS;

	switch (op) {
	case DDI_CTLOPS_INITCHILD:
		rval = init_child((dev_info_t *)arg);
		break;

	case DDI_CTLOPS_UNINITCHILD:
		impl_ddi_sunbus_removechild((dev_info_t *)arg);
		break;

	case DDI_CTLOPS_REPORTDEV: {
		if (rdip == (dev_info_t *)0)
			return (DDI_FAILURE);
		cmn_err(CE_CONT, "?acpinex: %s@%s, %s%d\n",
		    ddi_node_name(rdip), ddi_get_name_addr(rdip),
		    ddi_driver_name(rdip), ddi_get_instance(rdip));
		break;
	}

	default:
		rval = ddi_ctlops(dip, rdip, op, arg, result);
		break;
	}

	return (rval);
}
예제 #5
0
파일: main.c 프로젝트: Iron-Bound/trinity
/* Generate children*/
static void fork_children(void)
{
	while (shm->running_childs < max_children) {
		int childno;
		int pid = 0;

		if (shm->spawn_no_more == TRUE)
			return;

		/* a new child means a new seed, or the new child
		 * will do the same syscalls as the one in the child it's replacing.
		 * (special case startup, or we reseed unnecessarily)
		 */
		if (shm->ready == TRUE)
			reseed();

		/* Find a space for it in the pid map */
		childno = find_childno(EMPTY_PIDSLOT);
		if (childno == CHILD_NOT_FOUND) {
			outputerr("## Pid map was full!\n");
			dump_childnos();
			exit_main_fail();
		}

		fflush(stdout);
		pid = fork();

		if (pid == 0) {
			/* Child process. */
			init_child(childno);
			child_process();
			debugf("child %d %d exiting.\n", childno, getpid());
			close_logfile(&this_child->logfile);
			_exit(EXIT_SUCCESS);
		} else {
			if (pid == -1) {
				/* We failed, wait for a child to exit before retrying. */
				if (shm->running_childs > 0)
					return;

				output(0, "couldn't create child! (%s)\n", strerror(errno));
				panic(EXIT_FORK_FAILURE);
				exit_main_fail();
			}
		}

		shm->children[childno]->pid = pid;
		shm->running_childs++;

		debugf("Created child %d (pid:%d) [total:%d/%d]\n",
			childno, pid, shm->running_childs, max_children);

		if (shm->exit_reason != STILL_RUNNING)
			return;

	}
	shm->ready = TRUE;

	debugf("created enough children\n");
}
void quadtree_insert(void* element, QuadTreeNode* node){
//... Try to insert particle i at node n in quadtree
//     ... By construction, each leaf will contain either
//    ... 1 or 0 particles

  struct point_t middle_point = {0, 0};
  //printf("middle_point: %d\n", middle_point.x);
  //printf("middle_point: %d\n", middle_point.y);
  if(quadtree_is_leaf(node)){
    if(node->data != NULL){
      //just_one particle
      //add n's four children to the Quadtree
      node->children = (QuadTreeNode **)malloc(NUM_CHILDREN * sizeof(QuadTreeNode*));
      //printf("quadtree_insert: %d\n", ((struct cell_t*)(node->data))->x);
      //printf("quadtree_insert: %d\n", ((struct cell_t*)(node->data))->y);
      int i;
      for(i=0; i < NUM_CHILDREN; i++){
	QuadTreeNode* child = init_child(node, i);
	node->children[i] = child;
      }
      //move the particle already in n into the child
      //in which it lies
      // struct point_t middle_point = get_middle_point(node->rect);

      middle_point = get_middle_point(*node->rect);
      int p = get_position_forward(node, middle_point);
      //printf("quadtree_insert: %d\n", ((struct cell_t*)(node->data))->x);
      //printf("quadtree_insert: %d\n", ((struct cell_t*)(node->data))->y);
      printf("quadtree_insert over leaf node (%d, %d). Recursive call...\n", ((struct cell_t*)(node->data))->x, ((struct cell_t*)(node->data))->y);
      node->children[p]->data = node->data;
      node->data = NULL;

      //let c be child in which particle i lies
      //QuadInsert(i,c)
      int q = get_position(element, middle_point);
      quadtree_insert(element, node->children[q]);
    }else{
      //... n is a leaf
      //store particle i in node n
      node->data = element;
      printf("quadtree_insert over empty leaf. Element (%d, %d) finding its place.\n", ((struct cell_t*)(node->data))->x, ((struct cell_t*)(node->data))->y);
      //printf("quadtree_insert:ya %d\n", ((struct cell_t*)(node->data))->x);
      //printf("quadtree_insert:ya %d\n", ((struct cell_t*)(node->data))->y);
    }
  }else{
    //more than one nodes in the subtree
    //determine which child c of node n particle i lies in
    //QuadInsert(i,c)
    middle_point = get_middle_point(*node->rect);
    int q = get_position(element, middle_point);
    quadtree_insert(element, node->children[q]);
  }
}
예제 #7
0
int
main(int argc, char *argv[], char **envp)
{
    struct cmd_syndesc *ts;
    afs_int32 code;

#ifdef	AFS_AIX32_ENV
    /*
     * The following signal action for AIX is necessary so that in case of a 
     * crash (i.e. core is generated) we can include the user's data section 
     * in the core dump. Unfortunately, by default, only a partial core is
     * generated which, in many cases, isn't too useful.
     */
    struct sigaction nsa;

    sigemptyset(&nsa.sa_mask);
    nsa.sa_handler = SIG_DFL;
    nsa.sa_flags = SA_FULLDUMP;
    sigaction(SIGSEGV, &nsa, NULL);
#endif

    zero_argc = argc;
    zero_argv = argv;

    init_child(*argv);
    ts = cmd_CreateSyntax(NULL, CommandProc, 0, "change user's password");

#define aXFLAG 0
#define aPRINCIPAL 1
#define aPASSWORD 2
#define aNEWPASSWORD 3
#define aCELL 4
#define aSERVERS 5
#define aPIPE 6

    cmd_AddParm(ts, "-x", CMD_FLAG, CMD_OPTIONAL, "(obsolete, noop)");
    cmd_AddParm(ts, "-principal", CMD_SINGLE, CMD_OPTIONAL, "user name");
    cmd_AddParm(ts, "-password", CMD_SINGLE, CMD_OPTIONAL, "user's password");
    cmd_AddParm(ts, "-newpassword", CMD_SINGLE, CMD_OPTIONAL,
		"user's new password");
    cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");
    cmd_AddParm(ts, "-servers", CMD_LIST, CMD_OPTIONAL,
		"explicit list of servers");
    cmd_AddParm(ts, "-pipe", CMD_FLAG, CMD_OPTIONAL, "silent operation");

    code = cmd_Dispatch(argc, argv);
    exit(code != 0);
}
예제 #8
0
파일: list.c 프로젝트: ethanke/Corewar
t_process	*add_child(t_process *father)
{
  t_process	*tmp;
  t_process	*child;

  child = create_list();
  init_child(father, child);
  if (father->child == NULL)
    father->child = child;
  else
    {
      tmp = father->child;
      while (tmp->next != NULL)
	tmp = tmp->next;
      tmp->next = child;
    }
  return (child);
}
예제 #9
0
void ForkWrapper::start()
{
// Create the process & socket pair.
	int sockets[2];
	socketpair(AF_UNIX, SOCK_STREAM, 0, sockets);
	parent_fd = sockets[0];
	child_fd = sockets[1];

	pid = fork();

// Child process
	if(!pid)
	{
//printf("ForkWrapper::start %d %d\n", __LINE__, getpid());
		BC_Signals::reset_locks();
		BC_Signals::set_sighup_exit(1);
		init_child();
		run();
		_exit(0);
	}
}
예제 #10
0
/*
 * called in the OpenSIPS initialization phase by the main process.
 * forks the binary packet UDP receivers.
 *
 * @return: 0 on success
 */
int start_bin_receivers(void)
{
	pid_t pid;
	int i;

	if (udp_init_listener(bin, 0) != 0)
		return -1;

	for (i = 1; i <= bin_children; i++) {
		if ((pid = internal_fork("BIN receiver")) < 0) {
			LM_CRIT("Cannot fork binary packet receiver process!\n");
			return -1;
		}

		if (pid == 0) {
			LM_DBG("CHILD sock: %d\n", bin->socket);

			child_index = i;
			set_proc_attrs("BIN receiver %.*s ",
							bin->sock_str.len,
							bin->sock_str.s);
			bind_address = bin;

			if (init_child(PROC_BIN) < 0) {
				LM_ERR("init_child failed for BIN listener\n");
				report_failure_status();
				exit(-1);
			}

			bin_receive_loop();
			exit(-1);
		} else
			LM_DBG("PARENT sock: %d\n", bin->socket);
	}

	return 0;
}
예제 #11
0
void timeout_listener_process(int rank)
{
	struct sockaddr_un saddr_un;
	struct sockaddr_un *s_un;
	struct sockaddr_in saddr_in;
	struct sockaddr_in *s_in;
	struct sockaddr_in6 *s_in6;
	int connect_fd;
	char buffer[BUF_LEN];
	str dlg_id;
	char* p;
	unsigned int h_entry, h_id;
	str id;
	char* socket_name;
	unsigned short port;
	struct sockaddr* saddr;
	int len, i,n;
	int optval = 1;
	struct sockaddr rtpp_info;
	struct rtpp_notify_node *rtpp_lst;

	if (init_child(PROC_MODULE) != 0) {
		LM_ERR("cannot init child process");
		return;
	}

	if (strncmp("tcp:", rtpp_notify_socket.s, 4) == 0) {
		rtpp_notify_socket.s += 4;
		rtpp_notify_socket.len -= 4;
		p = strrchr(rtpp_notify_socket.s, ':');
		if (!p) {
			LM_ERR("invalid udp address <%.*s>\n", rtpp_notify_socket.len, rtpp_notify_socket.s);
			return;
		}
		n = p- rtpp_notify_socket.s;
		socket_name = (char *)pkg_malloc(n +1);
		if(!socket_name) {
			LM_ERR("no more private memory\n");
			return;
		}
		memcpy(socket_name, rtpp_notify_socket.s, n);
		socket_name[n] = '\0';

		id.s = p+1;
		id.len = rtpp_notify_socket.len - n -1;
		port= str2s(id.s, id.len, &n);
		if(n) {
			LM_ERR("Bad format for socket name. Expected ip:port\n");
			return;
		}
		memset(&saddr_in, 0, sizeof(saddr_in));
		saddr_in.sin_addr.s_addr = inet_addr(socket_name);
		saddr_in.sin_family = AF_INET;
		saddr_in.sin_port = htons(port);

		socket_fd = socket(AF_INET, SOCK_STREAM, 0);
		if (socket_fd == -1) {
			LM_ERR("can't create timeout socket\n");
			return;
		}
		saddr = (struct sockaddr*)&saddr_in;
		len = sizeof(saddr_in);
		LM_DBG("binding socket %d to %s:%d\n", socket_fd, socket_name, port);
	} else {
		if(strncmp("unix:", rtpp_notify_socket.s, 5) == 0) {
			rtpp_notify_socket.s += 5;
			rtpp_notify_socket.len -= 5;
		}

		/* create socket */
		socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
		if (socket_fd == -1) {
			LM_ERR("Failed to create unix socket\n");
			return;
		}

		memset(&saddr_un, 0, sizeof(struct sockaddr_un));
		saddr_un.sun_family = AF_LOCAL;
		strncpy(saddr_un.sun_path, rtpp_notify_socket.s,
				sizeof(saddr_un.sun_path) - 1);
		saddr = (struct sockaddr*)&saddr_un;
		len = sizeof(saddr_un);
		LM_DBG("binding unix socket %s\n", rtpp_notify_socket.s);
	}

	if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, (void*)&optval,
				sizeof(optval)) == -1) {
		LM_ERR("setsockopt failed %s\n", strerror(errno));
		return;
	}

	if (bind(socket_fd, saddr, len) == -1) {
		LM_ERR("failed to bind to socket: %s\n", strerror(errno));
		return;
	}

	/* open socket for listening */
	if(listen(socket_fd, 10) == -1) {
		LM_ERR("socket listen failed\n");
		close(socket_fd);
		return;
	}

	pfds = (struct pollfd *)pkg_malloc(pfds_size*sizeof(struct pollfd));
	if (!pfds) {
		LM_ERR("no more pkg memory\n");
		return;
	}
	pfds[0].fd = socket_fd;
	pfds[nfds++].events = POLLIN;

	for(;;) {
		nr_events = poll(pfds, nfds, -1);
		if (nr_events < 0)
			continue;

		/* check if the rtpproxy list needs updates */
		lock_get(rtpp_notify_h->lock);
		if (rtpp_notify_h->changed) {
			/* update list */
			update_rtpproxy_list();
			rtpp_notify_h->changed = 0;
		}
		lock_release(rtpp_notify_h->lock);

		/* there is a new connection */
		if (pfds[0].revents & POLLIN) {
			i = sizeof(rtpp_info);
			memset(&rtpp_info, 0, i);
			connect_fd = accept(socket_fd, &rtpp_info, (socklen_t *)&i);
			if(connect_fd < 0) {
				LM_ERR("socket accept failed\n");
				continue;
			}

			/* if it is a unix socket, try to authenticate it */
			if (rtpp_info.sa_family == AF_UNIX) {
				s_un = (struct sockaddr_un*)&rtpp_info;
				/* check if the socket is already opened */
				lock_get(rtpp_notify_h->lock);
				for (rtpp_lst = rtpp_notify_h->rtpp_list; rtpp_lst; rtpp_lst = rtpp_lst->next)
					if ( rtpp_lst->mode == 0 && !strcmp(rtpp_lst->addr, s_un->sun_path))
						break;

				/* if not found add a new one */
				if (!rtpp_lst) {
					/* leave the lock for a moment */
					lock_release(rtpp_notify_h->lock);
					rtpp_lst = (struct rtpp_notify_node*)
						shm_malloc(sizeof(struct rtpp_notify_node));
					if (!rtpp_lst) {
						LM_ERR("no shm more memory\n");
						return;
					}
					rtpp_lst->index = 0;
					rtpp_lst->mode = 0;
					rtpp_lst->addr = 0;

					/* copy the socket name */
					len = strlen(s_un->sun_path);
					rtpp_lst->addr = (char *)shm_malloc(len + 1);
					if (!rtpp_lst->addr) {
						LM_ERR("no more shm memory\n");
						return;
					}
					memcpy(rtpp_lst->addr, s_un->sun_path, len + 1);

					lock_get(rtpp_notify_h->lock);
					rtpp_lst->next = rtpp_notify_h->rtpp_list;
					if (!rtpp_notify_h->rtpp_list)
						rtpp_notify_h->rtpp_list = rtpp_lst;
				}
			} else {
				/* search if I can find this connection */
				if (rtpp_info.sa_family == AF_INET) {
					s_in = (struct sockaddr_in*)&rtpp_info;
					lock_get(rtpp_notify_h->lock);
					for (rtpp_lst = rtpp_notify_h->rtpp_list; rtpp_lst; rtpp_lst = rtpp_lst->next)
						if (rtpp_lst->mode == 1 &&
							memcmp(rtpp_lst->addr, &s_in->sin_addr.s_addr, 4) == 0)
							break;
				} else if (rtpp_info.sa_family == AF_INET6) {
					s_in6 = (struct sockaddr_in6*)&rtpp_info;
					lock_get(rtpp_notify_h->lock);
					for (rtpp_lst = rtpp_notify_h->rtpp_list; rtpp_lst; rtpp_lst = rtpp_lst->next)
						if (rtpp_lst->mode == 6 &&
							memcmp(rtpp_lst->addr, s_in6->sin6_addr.s6_addr, 16) == 0)
							break;
				} else {
					LM_ERR("cannot accept this type of connection\n");
					continue;
				}
			}

			if (!rtpp_lst) {
				lock_release(rtpp_notify_h->lock);
				LM_DBG("unknown rtpproxy -- ignoring\n");
				shutdown(connect_fd, SHUT_RDWR);
				close(connect_fd);
			} else {
				/* valid connection - checking if already connected */
				if (rtpp_lst->index) {
					LM_DBG("rtpproxy restarted - update connection status\n");
					shutdown(rtpp_lst->fd, SHUT_RDWR);
					close(rtpp_lst->fd);
				} else {
					rtpp_lst->index = nfds++;
					if (nfds > pfds_size) {
						pfds_size *= 2;
						pfds = (struct pollfd*)pkg_realloc(pfds,
								pfds_size*sizeof(struct pollfd));
					}
				}

				LM_DBG("rtpproxy accepted\n");
				pfds[rtpp_lst->index].fd = connect_fd;
				pfds[rtpp_lst->index].events = POLLIN;
				rtpp_lst->fd = connect_fd;
				lock_release(rtpp_notify_h->lock);
			}
			nr_events--;
		}

		for (i=1; (nr_events && i<nfds); i++)
		{
			if (!(pfds[i].revents & POLLIN))
				continue;
			nr_events--;

			do
				len = read(pfds[i].fd, buffer, BUF_LEN);
			while (len == -1 && errno == EINTR);

			if (len < 0) {
				LM_ERR("reading from socket failed: %s\n",strerror(errno));
				continue;
			}

			if (!len) {
				LM_DBG("closing rtpproxy\n");
				lock_get(rtpp_notify_h->lock);
				for (rtpp_lst=rtpp_notify_h->rtpp_list;
						rtpp_lst;rtpp_lst=rtpp_lst->next)
					if (rtpp_lst->index == i)
						break;
				if (!rtpp_lst) {
					LM_ERR("BUG - rtpproxy not found\n");
					lock_release(rtpp_notify_h->lock);
					continue;
				}
				rtpp_lst->index = 0;
				lock_release(rtpp_notify_h->lock);
				nfds--;
				shutdown(i, SHUT_RDWR);
				close(i);

				if (nfds == i)
					continue;

				pfds[i].fd = pfds[nfds].fd;
				lock_get(rtpp_notify_h->lock);
				for (rtpp_lst=rtpp_notify_h->rtpp_list; rtpp_lst; rtpp_lst=rtpp_lst->next)
					if (rtpp_lst->index == nfds)
						break;
				if (!rtpp_lst) {
					LM_ERR("BUG - rtpproxy index mismatch\n");
					lock_release(rtpp_notify_h->lock);
					continue;
				}
				rtpp_lst->index = i;
				lock_release(rtpp_notify_h->lock);
				continue;
			}
			dlg_id.s = buffer;
			dlg_id.len = len; /*strlen(buffer);*/
			trim(&dlg_id);
			LM_DBG("Timeout detected on call [%.*s]\n", len, buffer);
			/* the message is: h_entry.h_id */
			p = memchr(dlg_id.s, '.', dlg_id.len);
			if(p == NULL) {
				LM_ERR("Wrong formated message received from rtpproxy [%.*s]\n", len, buffer);
				continue;
			}
			id.s = dlg_id.s;
			id.len = p-dlg_id.s;
			if(str2int(&id, &h_entry)< 0) {
				LM_ERR("Wrong formated message received from rtpproxy [%.*s]\n", len, buffer);
				continue;
			}
			id.s =  p+ 1;
			id.len = dlg_id.len - id.len - 1;
			if(str2int(&id, &h_id)< 0) {
				LM_ERR("Wrong formated message received from rtpproxy [%.*s]\n", len, buffer);
				continue;
			}
			LM_DBG("hentry = %u, h_id = %u\n", h_entry, h_id);

			if(dlg_api.terminate_dlg(h_entry, h_id)< 0)
				LM_ERR("Failed to terminate dialog h_entry=[%u], h_id=[%u]\n", h_entry, h_id);
		}
	}
}
예제 #12
0
파일: main.c 프로젝트: srikanth007m/trinity
/* Generate children*/
static void fork_children(void)
{
	while (shm->running_childs < max_children) {
		int pidslot;
		int pid = 0;

		if (shm->spawn_no_more == TRUE)
			return;

		/* a new child means a new seed, or the new child
		 * will do the same syscalls as the one in the pidslot it's replacing.
		 * (special case startup, or we reseed unnecessarily)
		 */
		if (shm->ready == TRUE)
			reseed();

		/* Find a space for it in the pid map */
		pidslot = find_pid_slot(EMPTY_PIDSLOT);
		if (pidslot == PIDSLOT_NOT_FOUND) {
			outputerr("## Pid map was full!\n");
			dump_pid_slots();
			exit(EXIT_FAILURE);
		}

		if (logging == TRUE) {
			int fd;

			fd = fileno(shm->logfiles[pidslot]);
			if (ftruncate(fd, 0) == 0)
				lseek(fd, 0, SEEK_SET);
		}

		(void)alarm(0);
		fflush(stdout);
		pid = fork();

		if (pid == 0) {
			/* Child process. */
			init_child(pidslot);
			child_process(pidslot);
			debugf("child %d exiting.\n", pidslot);
			_exit(EXIT_SUCCESS);
		} else {
			if (pid == -1) {
				output(0, "couldn't create child! (%s)\n", strerror(errno));
				shm->exit_reason = EXIT_FORK_FAILURE;
				exit(EXIT_FAILURE);
			}
		}

		shm->pids[pidslot] = pid;
		shm->running_childs++;

		debugf("Created child %d in pidslot %d [total:%d/%d]\n",
			shm->pids[pidslot], pidslot,
			shm->running_childs, max_children);

		if (shm->exit_reason != STILL_RUNNING)
			return;

	}
	shm->ready = TRUE;

	debugf("created enough children\n");
}
예제 #13
0
/*! \brief starts the tcp processes */
int tcp_init_children(int *chd_rank)
{
	int r;
	//int sockfd[2];
	int reader_fd[2]; /* for comm. with the tcp children read  */
	pid_t pid;
	struct socket_info *si;
	atomic_t *load_p;
	
	/* estimate max fd. no:
	 * 1 tcp send unix socket/all_proc, 
	 *  + 1 udp sock/udp proc + 1 tcp_child sock/tcp child*
	 *  + no_listen_tcp */
	for(r=0, si=tcp_listen; si; si=si->next, r++);
#ifdef USE_TLS
	if (! tls_disable)
		for (si=tls_listen; si; si=si->next, r++);
#endif
	
	tcp_max_fd_no=counted_processes*2 +r-1 /* timer */ +3; /* stdin/out/err*/
	tcp_max_fd_no+=tcp_max_connections;
	
	/* create the tcp sock_info structures */
	/* copy the sockets --moved to main_loop*/
	
	load_p = shm_malloc(sizeof(atomic_t));
	if (!load_p)
		goto error;
	memset(load_p,0,sizeof(atomic_t));
	register_tcp_load_stat(load_p);

	/* fork children & create the socket pairs*/
	for(r=0; r<tcp_children_no; r++){
		/*if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd)<0){
			LM_ERR("socketpair failed: %s\n", strerror(errno));
			goto error;
		}*/
		if (socketpair(AF_UNIX, SOCK_STREAM, 0, reader_fd)<0){
			LM_ERR("socketpair failed: %s\n", strerror(errno));
			goto error;
		}
		
		(*chd_rank)++;
		pid=internal_fork("SIP receiver TCP");
		if (pid<0){
			LM_ERR("fork failed\n");
			goto error;
		}else if (pid>0){
			/* parent */
			close(reader_fd[1]);
			tcp_children[r].pid=pid;
			tcp_children[r].proc_no=process_no;
			tcp_children[r].busy=0;
			tcp_children[r].n_reqs=0;
			tcp_children[r].unix_sock=reader_fd[0];
		}else{
			/* child */
			set_proc_attrs("TCP receiver");
			pt[process_no].idx=r;
			pt[process_no].load = load_p;
			bind_address=0; /* force a SEGFAULT if someone uses a non-init.
							   bind address on tcp */
			if (init_child(*chd_rank) < 0) {
				LM_ERR("init_children failed\n");
				exit(-1);
			}
	
			tcp_receive_loop(reader_fd[1]);
			exit(-1);
		}
	}
	return 0;
error:
	return -1;
}
예제 #14
0
파일: net_tcp.c 프로젝트: Danfx/opensips
int tcp_start_processes(int *chd_rank, int *startup_done)
{
	int r, n;
	int reader_fd[2]; /* for comm. with the tcp children read  */
	pid_t pid;
	struct socket_info *si;
	stat_var *load_p = NULL;

	if (tcp_disabled)
		return 0;

	/* estimate max fd. no:
	 * 1 tcp send unix socket/all_proc,
	 *  + 1 udp sock/udp proc + 1 tcp_child sock/tcp child*
	 *  + no_listen_tcp */
	for( r=0,n=PROTO_FIRST ; n<PROTO_LAST ; n++ )
		if ( is_tcp_based_proto(n) )
			for(si=protos[n].listeners; si ; si=si->next,r++ );

	if (register_tcp_load_stat( &load_p )!=0) {
		LM_ERR("failed to init tcp load statistic\n");
		goto error;
	}

	/* start the TCP workers & create the socket pairs */
	for(r=0; r<tcp_children_no; r++){
		/* create sock to communicate from TCP main to worker */
		if (socketpair(AF_UNIX, SOCK_STREAM, 0, reader_fd)<0){
			LM_ERR("socketpair failed: %s\n", strerror(errno));
			goto error;
		}

		(*chd_rank)++;
		pid=internal_fork("SIP receiver TCP");
		if (pid<0){
			LM_ERR("fork failed\n");
			goto error;
		}else if (pid>0){
			/* parent */
			close(reader_fd[1]);
			tcp_children[r].pid=pid;
			tcp_children[r].proc_no=process_no;
			tcp_children[r].busy=0;
			tcp_children[r].n_reqs=0;
			tcp_children[r].unix_sock=reader_fd[0];
		}else{
			/* child */
			set_proc_attrs("TCP receiver");
			pt[process_no].idx=r;
			pt[process_no].load = load_p;
			if (init_child(*chd_rank) < 0) {
				LM_ERR("init_children failed\n");
				report_failure_status();
				if (startup_done)
					*startup_done = -1;
				exit(-1);
			}

			/* was startup route executed so far ? */
			if (startup_done!=NULL && *startup_done==0 && r==0) {
				LM_DBG("runing startup for first TCP\n");
				if(run_startup_route()< 0) {
					LM_ERR("Startup route processing failed\n");
					report_failure_status();
					*startup_done = -1;
					exit(-1);
				}
				*startup_done = 1;
			}

			report_conditional_status( 1, 0);

			tcp_worker_proc( reader_fd[1] );
			exit(-1);
		}
	}

	/* wait for the startup route to be executed */
	if (startup_done)
		while (!(*startup_done)) {
			usleep(5);
			handle_sigs();
		}

	/* start the TCP manager process */
	if ( (pid=internal_fork( "TCP main"))<0 ) {
		LM_CRIT("cannot fork tcp main process\n");
		goto error;
	}else if (pid==0){
			/* child */
		/* close the TCP inter-process sockets */
		close(unix_tcp_sock);
		unix_tcp_sock = -1;
		close(pt[process_no].unix_sock);
		pt[process_no].unix_sock = -1;

		report_conditional_status( (!no_daemon_mode), 0);

		tcp_main_server();
		exit(-1);
	}

	return 0;
error:
	return -1;
}
예제 #15
0
/*
 * Spawn listeners
 */
int init_unixsock_children(void)
{
	int i;
	pid_t pid;
#ifdef USE_TCP
	int sockfd[2];
#endif

	if (!unixsock_name || *unixsock_name == '\0') {
		return 1;
	}

	if (get_uptime() < 0) {
		return -1;
	}
	
        if (register_core_commands() < 0) {
		close(rx_sock);
		close(tx_sock);
		return -1;
	}

	for(i = 0; i < unixsock_children; i++) {
		process_no++;
#ifdef USE_TCP
		if(!tcp_disable){
 			if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd)<0){
				LOG(L_ERR, "ERROR: init_unixsock_server: socketpair"
						" failed: %s\n", strerror(errno));
				return -1;
			}
		}
#endif
		pid = fork();
		if (pid < 0) {
			LOG(L_ERR, "init_unixsock_server: Unable to fork: %s\n",
			    strerror(errno));
			close(rx_sock);
			close(tx_sock);
			return -1;
		} else if (pid == 0) { /* child */
#ifdef USE_TCP
			if (!tcp_disable){
				close(sockfd[0]);
				unix_tcp_sock=sockfd[1];
			}
#endif
			if (init_child(PROC_UNIXSOCK) < 0) {
				LOG(L_ERR, "init_unixsock_server: Error in "
				    "init_child\n");
				close(rx_sock);
				close(tx_sock);
				return -1;
			}

			unix_server_loop(); /* Never returns */
		}

		     /* Parent */
		pt[process_no].pid = pid;
		strncpy(pt[process_no].desc, "unix domain socket server", 
			MAX_PT_DESC);
#ifdef USE_TCP
		if (!tcp_disable){
			close(sockfd[1]);
			pt[process_no].unix_sock=sockfd[0];
			pt[process_no].idx=-1; /* this is not a "tcp"
									  process*/
		}
#endif

	}

	DBG("init_unixsock_server: Unix domain socket server successfully initialized @ %s\n",
	    unixsock_name);
	return 1;
}
예제 #16
0
/*-----------------------------------------------------------------------------
    main
-----------------------------------------------------------------------------*/
int main(int argc, char** argv)
{
	if (argc < 2)
	{
		fprintf(stderr, "Syntax: %s <tracee> [<tracee args>]\n", argv[0]);
		return -1;
	}

	main_child = fork();
	if (main_child == 0)
	{
		int argv_len = 0;

		for (int i = 1; i < argc; ++i)
			if (argv[i])
				argv_len += strlen(argv[i]) + 1;

		char* new_argv = new char[argv_len + 1];
		for (int i = 1; i < argc; ++i)
		{
			if (i > 1)
				strcat(new_argv, " ");
			strcat(new_argv, argv[i]);
		}
		char* execve_args[] = {(char*)"sh", (char*)"-c", new_argv, NULL};

		ptrace(PTRACE_TRACEME, 0, 0, 0);
		execv("/bin/sh", execve_args);
	}
	else
	{
		unsigned char first_fork = 1;
		int status;
		pid_t pid;
		std::map<pid_t, struct minimal_childstate*>::iterator it;
		struct minimal_childstate* child = init_child(main_child);

		childs.insert(std::pair<pid_t, struct minimal_childstate*>(main_child, child));

		// wait for the main child first to set the ptrace options
		if ((waitpid(-1, &status, 0) == main_child) && WIFSTOPPED(status))
		{
			child_set_options(child);
			ptrace(PTRACE_SYSCALL, main_child, NULL, 0);
		}
		else
		{
			fprintf(stderr, "ERROR: Main child initialization failed\n");
			force_shutdown();
		}

		while ((pid = waitpid(-1, &status, __WALL | WUNTRACED)) != -1)
		{
			it = childs.find(pid);
			if (it == childs.end())
			{
				if (childs.find(pid) == childs.end())
					childs.insert(std::pair<pid_t, struct minimal_childstate*>(pid, init_child(pid)));
			}
			else
			{
				child = it->second;
			}

			if (WIFEXITED(status))
			{
				child->child_exited = 1;
				check_shutdown();
				ptrace(PTRACE_SYSCALL, pid, NULL, 0);
			}
			else if (WIFSTOPPED(status))
			{
				if (WSTOPSIG(status) == (SIGTRAP|0x80))
				{
					if (!child->child_in_syscall)
					{
						long syscall_no = ptrace(PTRACE_PEEKUSER, pid, 8 * ORIG_RAX, NULL);
						if (is_whitelisted_syscall(syscall_no))
							child->child_syscalls_whitelisted++;
						child->child_syscalls++;
					}
					child->child_in_syscall = !child->child_in_syscall;
					ptrace(PTRACE_SYSCALL, pid, NULL, 0);
				}
				else if (WSTOPSIG(status) == SIGTRAP)
				{
					int event = ((status & 0x000F0000) >> 16);
					if (event == PTRACE_EVENT_FORK || event == PTRACE_EVENT_VFORK || event == PTRACE_EVENT_CLONE)
					{
						long newpid;
						ptrace(PTRACE_GETEVENTMSG, pid, 0, &newpid);
						if (childs.find(newpid) == childs.end())
							childs.insert(std::pair<pid_t, struct minimal_childstate*>(newpid, init_child(newpid)));

						//printf("fork event from child: %d [== FORK ==>] %d\n", pid, (pid_t)newpid);

						if (first_fork)
						{
							first_fork = 0;
							gettimeofday(&start_time, NULL);
						}
					}
					else
					{
						//fprintf(stderr, "ERROR: Unexpected SIGTRAP from child %d - event: %d\n", pid, event);
						//force_shutdown();
					}

					ptrace(PTRACE_SYSCALL, pid, NULL, 0);
				}
				else if (WSTOPSIG(status) == SIGSTOP)
				{
					if (!child->child_resumed)
						child->child_resumed = 1;
					else
						child->child_signals++;
					ptrace(PTRACE_SYSCALL, pid, NULL, 0);
				}
				else
				{
					child->child_signals++;
					ptrace(PTRACE_SYSCALL, pid, NULL, (void*)WSTOPSIG(status));
				}
			}
			else
			{
예제 #17
0
파일: timer.c 프로젝트: NormB/opensips
int start_timer_processes(void)
{
    struct sr_timer_process *tpl;
    pid_t pid;

    /*
     * A change of the way timers were run. In the pre-1.5 times,
     * all timer processes had their own jiffies and just the first
     * one was doing the global ones. Now, there's a separate process
    * that increases jiffies - run_timer_process_jif(), and the rest
     * just use that one.
     *
     * The main reason for this change was when a function that relied
     * on jiffies for its timeouts got called from the timer thread and
     * was unable to detect timeouts.
     */

    if ( (pid=internal_fork("time_keeper"))<0 ) {
        LM_CRIT("cannot fork time keeper process\n");
        goto error;
    } else if (pid==0) {
        /* new process */
        clean_write_pipeend();

        run_timer_process_jif();
        exit(-1);
    }

    for( tpl=timer_proc_list ; tpl ; tpl=tpl->next ) {
        if (tpl->timer_list==NULL && tpl->utimer_list==NULL)
            continue;
        /* fork a new process */
        if ( (pid=internal_fork("timer"))<0 ) {
            LM_CRIT("cannot fork timer process\n");
            goto error;
        } else if (pid==0) {
            /* new process */
            /* run init if required */
            if ( tpl->flags&TIMER_PROC_INIT_FLAG ) {
                LM_DBG("initializing timer\n");
                inc_init_timer();
                if (init_child(PROC_TIMER)<0 ) {
                    LM_ERR("init_child failed for timer proc\n");

                    if (send_status_code(-1) < 0)
                        LM_ERR("failed to send status code\n");
                    clean_write_pipeend();

                    exit(-1);
                }

                if (!no_daemon_mode && send_status_code(0) < 0)
                    LM_ERR("failed to send status code\n");
                clean_write_pipeend();
            } else
                clean_write_pipeend();

            run_timer_process( tpl );
            exit(-1);
        }
    }

    return 0;
error:
    return -1;
}
예제 #18
0
파일: evapi_mod.c 프로젝트: SipSeb/kamailio
/**
 * @brief Initialize async module children
 */
static int child_init(int rank)
{
	int pid;
	int i;

	if (rank==PROC_INIT) {
		if(evapi_init_notify_sockets()<0) {
			LM_ERR("failed to initialize notify sockets\n");
			return -1;
		}
		return 0;
	}

	if (rank!=PROC_MAIN) {
		if(_evapi_dispatcher_pid!=getpid()) {
			evapi_close_notify_sockets_parent();
		}
		return 0;
	}

	pid=fork_process(PROC_NOCHLDINIT, "EvAPI Dispatcher", 1);
	if (pid<0)
		return -1; /* error */
	if(pid==0) {
		/* child */
		_evapi_dispatcher_pid = getpid();

		/* do child init to allow execution of rpc like functions */
		if(init_child(PROC_RPC) < 0) {
			LM_DBG("failed to do RPC child init for dispatcher\n");
			return -1;
		}
		/* initialize the config framework */
		if (cfg_child_init())
			return -1;
		/* main function for dispatcher */
		evapi_close_notify_sockets_child();
		if(evapi_run_dispatcher(_evapi_bind_addr, _evapi_bind_port)<0) {
			LM_ERR("failed to initialize evapi dispatcher process\n");
			return -1;
		}
	}

	for(i=0; i<_evapi_workers; i++) {
		pid=fork_process(PROC_RPC, "EvAPI Worker", 1);
		if (pid<0)
			return -1; /* error */
		if(pid==0) {
			/* child */

			/* initialize the config framework */
			if (cfg_child_init())
				return -1;
			/* main function for workers */
			if(evapi_run_worker(i+1)<0) {
				LM_ERR("failed to initialize worker process: %d\n", i);
				return -1;
			}
		}
	}

	return 0;
}
예제 #19
0
파일: main.c 프로젝트: rantala/trinity
static void fork_children(void)
{
	int pidslot;
	static char childname[17];

	/* Generate children*/

	while (shm->running_childs < shm->max_children) {
		int pid = 0;

		/* Find a space for it in the pid map */
		pidslot = find_pid_slot(EMPTY_PIDSLOT);
		if (pidslot == PIDSLOT_NOT_FOUND) {
			printf("[%d] ## Pid map was full!\n", getpid());
			dump_pid_slots();
			exit(EXIT_FAILURE);
		}

		(void)alarm(0);
		fflush(stdout);
		pid = fork();
		if (pid != 0)
			shm->pids[pidslot] = pid;
		else {
			/* Child process. */
			int ret = 0;

			mask_signals_child();

			memset(childname, 0, sizeof(childname));
			sprintf(childname, "trinity-child%d", pidslot);
			prctl(PR_SET_NAME, (unsigned long) &childname);

			oom_score_adj(500);

			/* Wait for parent to set our pidslot */
			while (shm->pids[pidslot] != getpid()) {
				/* Make sure parent is actually alive to wait for us. */
				ret = pid_alive(shm->parentpid);
				if (ret != 0) {
					shm->exit_reason = EXIT_SHM_CORRUPTION;
					printf("[%d] " BUGTXT "parent (%d) went away!\n", getpid(), shm->parentpid);
					sleep(20000);
				}
			}

			init_child(pidslot);

			ret = child_process(pidslot);

			output(1, "child %d exiting\n", getpid());

			_exit(ret);
		}
		shm->running_childs++;
		debugf("[%d] Created child %d in pidslot %d [total:%d/%d]\n",
			getpid(), shm->pids[pidslot], pidslot,
			shm->running_childs, shm->max_children);

		if (shm->exit_reason != STILL_RUNNING)
			return;

	}
	debugf("[%d] created enough children\n", getpid());
}
예제 #20
0
파일: main.c 프로젝트: OPSF/uClinux
/* main loop */
int main_loop()
{
	int  i;
	pid_t pid;
	struct socket_info* si;
#ifdef USE_TCP
	int sockfd[2];
#endif

	/* one "main" process and n children handling i/o */

	is_main=0;
	if (dont_fork){
#ifdef STATS
		setstats( 0 );
#endif
		if (udp_listen==0){
			LOG(L_ERR, "ERROR: no fork mode requires at least one"
					" udp listen address, exiting...\n");
			goto error;
		}
		/* only one address, we ignore all the others */
		if (udp_init(udp_listen)==-1) goto error;
		bind_address=udp_listen;
		sendipv4=bind_address;
		sendipv6=bind_address; /*FIXME*/
		if (udp_listen->next){
			LOG(L_WARN, "WARNING: using only the first listen address"
						" (no fork)\n");
		}
		/* initialize fifo server -- we need to open the fifo before
		 * do_suid() and start the fifo server after all the socket 
		 * are initialized, to inherit them*/
		if (init_fifo_server()<0) {
			LOG(L_ERR, "initializing fifo server failed\n");
			goto error;
		}
		 /* Initialize Unix domain socket server */
		if (init_unixsock_socket()<0) {
			LOG(L_ERR, "Error while creating unix domain sockets\n");
			goto error;
		}
		if (do_suid()==-1) goto error; /* try to drop privileges */
		/* process_no now initialized to zero -- increase from now on
		   as new processes are forked (while skipping 0 reserved for main 
		*/

		/* we need another process to act as the timer*/
#ifdef USE_TCP
		/* if we are using tcp we always need a timer process,
		 * we cannot count on select timeout to measure time
		 * (it works only on linux)
		 */
		if ((!tcp_disable)||(timer_list))
#else
		if (timer_list)
#endif
		{
				process_no++;
				if ((pid=fork())<0){
					LOG(L_CRIT,  "ERROR: main_loop: Cannot fork\n");
					goto error;
				}
				
				if (pid==0){
					/* child */
					/* timer!*/
					/* process_bit = 0; */
					if (init_child(PROC_TIMER) < 0) {
						LOG(L_ERR, "timer: init_child failed\n");
						goto error;
					}
					for(;;){
						sleep(TIMER_TICK);
						timer_ticker();
					}
				}else{
						pt[process_no].pid=pid; /*should be shared mem anyway*/
						strncpy(pt[process_no].desc, "timer", MAX_PT_DESC );
				}
		}

		/* if configured, start a server for accepting FIFO commands,
		 * we need to do it after all the sockets are initialized, to 
		 * inherit them*/
		if (start_fifo_server()<0) {
			LOG(L_ERR, "starting fifo server failed\n");
			goto error;
		}

		if (init_unixsock_children()<0) {
			LOG(L_ERR, "Error while initializing Unix domain socket server\n");
			goto error;
		}

		/* main process, receive loop */
		process_no=0; /*main process number*/
		pt[process_no].pid=getpid();
		snprintf(pt[process_no].desc, MAX_PT_DESC, 
			"stand-alone receiver @ %s:%s", 
			 bind_address->name.s, bind_address->port_no_str.s );
		
		
		     /* We will call child_init even if we
		      * do not fork - and it will be called with rank 1 because
		      * in fact we behave like a child, not like main process
		      */

		if (init_child(1) < 0) {
			LOG(L_ERR, "main_dontfork: init_child failed\n");
			goto error;
		}

		is_main=1; /* hack 42: call init_child with is_main=0 in case
					 some modules wants to fork a child */
		
		return udp_rcv_loop();
	}else{
		/* process_no now initialized to zero -- increase from now on
		   as new processes are forked (while skipping 0 reserved for main )
		*/

		for(si=udp_listen;si;si=si->next){
			/* create the listening socket (for each address)*/
			/* udp */
			if (udp_init(si)==-1) goto error;
			/* get first ipv4/ipv6 socket*/
			if ((si->address.af==AF_INET)&&
					((sendipv4==0)||(sendipv4->flags&SI_IS_LO)))
				sendipv4=si;
	#ifdef USE_IPV6
			if((sendipv6==0)&&(si->address.af==AF_INET6))
				sendipv6=si;
	#endif
		}
#ifdef USE_TCP
		if (!tcp_disable){
			for(si=tcp_listen; si; si=si->next){
				/* same thing for tcp */
				if (tcp_init(si)==-1)  goto error;
				/* get first ipv4/ipv6 socket*/
				if ((si->address.af==AF_INET)&&
						((sendipv4_tcp==0)||(sendipv4_tcp->flags&SI_IS_LO)))
					sendipv4_tcp=si;
		#ifdef USE_IPV6
				if((sendipv6_tcp==0)&&(si->address.af==AF_INET6))
					sendipv6_tcp=si;
		#endif
			}
		}
#ifdef USE_TLS
		if (!tls_disable){
			for(si=tls_listen; si; si=si->next){
				/* same as for tcp*/
				if (tls_init(si)==-1)  goto error;
				/* get first ipv4/ipv6 socket*/
				if ((si->address.af==AF_INET)&&
						((sendipv4_tls==0)||(sendipv4_tls->flags&SI_IS_LO)))
					sendipv4_tls=si;
		#ifdef USE_IPV6
				if((sendipv6_tls==0)&&(si->address.af==AF_INET6))
					sendipv6_tls=si;
		#endif
			}
		}
#endif /* USE_TLS */
#endif /* USE_TCP */

		/* initialize fifo server -- we need to open the fifo before
		 * do_suid() and start the fifo server after all the socket 
		 * are initialized, to inherit them*/
		if (init_fifo_server()<0) {
			LOG(L_ERR, "initializing fifo server failed\n");
			goto error;
		}
		 /* Initialize Unix domain socket server */
		     /* Create the unix domain sockets */
		if (init_unixsock_socket()<0) {
			LOG(L_ERR, "ERROR: Could not create unix domain sockets\n");
			goto error;
		}

			/* all processes should have access to all the sockets (for sending)
			 * so we open all first*/
		if (do_suid()==-1) goto error; /* try to drop privileges */

		/* if configured, start a server for accepting FIFO commands,
		 * we need to do it after all the sockets are initialized, to 
		 * inherit them*/
		if (start_fifo_server()<0) {
			LOG(L_ERR, "starting fifo server failed\n");
			goto error;
		}
		     /* Spawn children listening on unix domain socket if and only if
		      * the unix domain socket server has not been disabled (i == 0)
		      */
		if (init_unixsock_children()<0) {
			LOG(L_ERR, "ERROR: Could not initialize unix domain socket server\n");
			goto error;
		}

		/* udp processes */
		for(si=udp_listen; si; si=si->next){
			for(i=0;i<children_no;i++){
				process_no++;
#ifdef USE_TCP
				if(!tcp_disable){
		 			if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd)<0){
						LOG(L_ERR, "ERROR: main_loop: socketpair failed: %s\n",
							strerror(errno));
						goto error;
					}
				}
#endif
				if ((pid=fork())<0){
					LOG(L_CRIT,  "main_loop: Cannot fork\n");
					goto error;
				}else if (pid==0){
					     /* child */
#ifdef USE_TCP
					if (!tcp_disable){
						close(sockfd[0]);
						unix_tcp_sock=sockfd[1];
					}
#endif
					bind_address=si; /* shortcut */
					if (init_child(i + 1) < 0) {
						LOG(L_ERR, "init_child failed\n");
						goto error;
					}
#ifdef STATS
					setstats( i+r*children_no );
#endif
					return udp_rcv_loop();
				}else{
						pt[process_no].pid=pid; /*should be in shared mem.*/
						snprintf(pt[process_no].desc, MAX_PT_DESC,
							"receiver child=%d sock= %s:%s", i, 	
							si->name.s, si->port_no_str.s );
#ifdef USE_TCP
						if (!tcp_disable){
							close(sockfd[1]);
							pt[process_no].unix_sock=sockfd[0];
							pt[process_no].idx=-1; /* this is not a "tcp"
													  process*/
						}
#endif
				}
			}
			/*parent*/
			/*close(udp_sock)*/; /*if it's closed=>sendto invalid fd errors?*/
		}
	}

	/*this is the main process*/
	bind_address=0;				/* main proc -> it shouldn't send anything, */
	

#ifdef USE_TCP
	/* if we are using tcp we always need the timer */
	if ((!tcp_disable)||(timer_list))
#else
	if (timer_list)
#endif
	{
#ifdef USE_TCP
		if (!tcp_disable){
 			if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd)<0){
				LOG(L_ERR, "ERROR: main_loop: socketpair failed: %s\n",
					strerror(errno));
				goto error;
			}
		}
#endif
		/* fork again for the attendant process*/
		process_no++;
		if ((pid=fork())<0){
			LOG(L_CRIT, "main_loop: cannot fork timer process\n");
			goto error;
		}else if (pid==0){
			/* child */
			/* is_main=0; */
#ifdef USE_TCP
			if (!tcp_disable){
				close(sockfd[0]);
				unix_tcp_sock=sockfd[1];
			}
#endif
			if (init_child(PROC_TIMER) < 0) {
				LOG(L_ERR, "timer: init_child failed\n");
				goto error;
			}
			
			for(;;){
				/* debug:  instead of doing something useful */
				/* (placeholder for timers, etc.) */
				sleep(TIMER_TICK);
				/* if we received a signal => TIMER_TICK may have not elapsed*/
				timer_ticker();
			}
		}else{
			pt[process_no].pid=pid;
			strncpy(pt[process_no].desc, "timer", MAX_PT_DESC );
#ifdef USE_TCP
			if(!tcp_disable){
						close(sockfd[1]);
						pt[process_no].unix_sock=sockfd[0];
						pt[process_no].idx=-1; /* this is not a "tcp" process*/
			}
#endif
		}
	}
#ifdef USE_TCP
		if (!tcp_disable){
				/* start tcp  & tls receivers */
			if (tcp_init_children()<0) goto error;
				/* start tcp+tls master proc */
			process_no++;
			if ((pid=fork())<0){
				LOG(L_CRIT, "main_loop: cannot fork tcp main process\n");
				goto error;
			}else if (pid==0){
				/* child */
				/* is_main=0; */
				if (init_child(PROC_TCP_MAIN) < 0) {
					LOG(L_ERR, "tcp_main: error in init_child\n");
					goto error;
				}
				tcp_main_loop();
			}else{
				pt[process_no].pid=pid;
				strncpy(pt[process_no].desc, "tcp main process", MAX_PT_DESC );
				pt[process_no].unix_sock=-1;
				pt[process_no].idx=-1; /* this is not a "tcp" process*/
				unix_tcp_sock=-1;
			}
		}
#endif
	/* main */
	pt[0].pid=getpid();
	strncpy(pt[0].desc, "attendant", MAX_PT_DESC );
#ifdef USE_TCP
	if(!tcp_disable){
		pt[process_no].unix_sock=-1;
		pt[process_no].idx=-1; /* this is not a "tcp" process*/
		unix_tcp_sock=-1;
	}
#endif
	/*DEBUG- remove it*/
#ifdef DEBUG
	fprintf(stderr, "\n% 3d processes (%3d), % 3d children * "
			"listening addresses + tcp listeners + tls listeners"
			"+ main + fifo %s\n", process_no+1, process_count(), children_no,
			(timer_list)?"+ timer":"");
	for (r=0; r<=process_no; r++){
		fprintf(stderr, "% 3d   % 5d - %s\n", r, pt[r].pid, pt[r].desc);
	}
#endif
	process_no=0; 
	/* process_bit = 0; */
	is_main=1;
	
	if (init_child(PROC_MAIN) < 0) {
		LOG(L_ERR, "main: error in init_child\n");
		goto error;
	}
	for(;;){
			pause();
			handle_sigs();
	}
	
	
	/*return 0; */
 error:
	is_main=1;  /* if we are here, we are the "main process",
				  any forked children should exit with exit(-1) and not
				  ever use return */
	return -1;

}
예제 #21
0
int start_module_procs(void)
{
	struct sr_module *m;
	unsigned int n;
	unsigned int l;
	pid_t x;

	for( m=modules ; m ; m=m->next) {
		if (m->exports->procs==NULL)
			continue;
		for( n=0 ; m->exports->procs[n].name ; n++) {
			if ( !m->exports->procs[n].no || !m->exports->procs[n].function )
				continue;
			/* run pre-fork function */
			if (m->exports->procs[n].pre_fork_function)
				if (m->exports->procs[n].pre_fork_function()!=0) {
					LM_ERR("pre-fork function failed for process \"%s\" "
						"in module %s\n",
						m->exports->procs[n].name, m->exports->name);
					return -1;
				}
			/* fork the processes */
			for ( l=0; l<m->exports->procs[n].no ; l++) {
				LM_DBG("forking process \"%s\"/%d for module %s\n",
					m->exports->procs[n].name, l, m->exports->name);
				x = internal_fork(m->exports->procs[n].name);
				if (x<0) {
					LM_ERR("failed to fork process \"%s\"/%d for module %s\n",
						m->exports->procs[n].name, l, m->exports->name);
					return -1;
				} else if (x==0) {
					/* new process */
					/* initialize the process for the rest of the modules */
					if ( m->exports->procs[n].flags&PROC_FLAG_INITCHILD ) {
						if (init_child(PROC_MODULE) < 0) {
							LM_ERR("error in init_child for PROC_MODULE\n");
							if (send_status_code(-1) < 0)
								LM_ERR("failed to send status code\n");
							clean_write_pipeend();
							exit(-1);
						}

						if (send_status_code(0) < 0)
							LM_ERR("failed to send status code\n");
						clean_write_pipeend();
					} else
						clean_write_pipeend();

					/* run the function */
					m->exports->procs[n].function(l);
					/* we shouldn't get here */
					exit(0);
				}
			}
			/* run post-fork function */
			if (m->exports->procs[n].post_fork_function)
				if (m->exports->procs[n].post_fork_function()!=0) {
					LM_ERR("post-fork function failed for process \"%s\" "
						"in module %s\n",
						m->exports->procs[n].name, m->exports->name);
					return -1;
				}
		}
	}

	return 0;
}
예제 #22
0
int open_fifo_server()
{
	char *t;
	struct stat filestat;
	int n;
#ifdef USE_TCP
	int sockfd[2];
#endif

	if (fifo==NULL) {
		DBG("DBG: open_fifo_server: no fifo will be opened\n");
		/* everything is ok, we just do not want to start */
		return 1;
	}
	if (strlen(fifo)==0) {
		DBG("DBG: open_fifo_server: fifo disabled\n");
		return 1;
	}
	DBG("DBG: open_uac_fifo: opening fifo...\n");
	n=stat(fifo, &filestat);
	if (n==0){
		/* FIFO exist, delete it (safer) */
		if (unlink(fifo)<0){
			LOG(L_ERR, "ERROR: open_fifo_server: cannot delete old fifo (%s):"
					" %s\n", fifo, strerror(errno));
			return -1;
		}
	}else if (n<0 && errno!=ENOENT){
		LOG(L_DBG, "DEBUG: open_fifo_server: FIFO stat failed: %s\n",
			strerror(errno));
	}
	/* create FIFO ... */
		if ((mkfifo(fifo, fifo_mode)<0)) {
			LOG(L_ERR, "ERROR: open_fifo_server; can't create FIFO: "
					"%s (mode=%d)\n",
					strerror(errno), fifo_mode);
			return -1;
		} 
		DBG("DEBUG: FIFO created @ %s\n", fifo );
		if ((chmod(fifo, fifo_mode)<0)) {
			LOG(L_ERR, "ERROR: open_fifo_server; can't chmod FIFO: "
					"%s (mode=%d)\n",
					strerror(errno), fifo_mode);
			return -1;
		}
	DBG("DEBUG: fifo %s opened, mode=%d\n", fifo, fifo_mode );
	time(&up_since);
	t=ctime(&up_since);
	if (strlen(t)+1>=MAX_CTIME_LEN) {
		LOG(L_ERR, "ERROR: open_fifo_server: "
			"too long date %d\n", (int)strlen(t));
		return -1;
	}
	memcpy(up_since_ctime,t,strlen(t)+1);
#ifdef USE_TCP
	if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd)<0){
			LOG(L_ERR, "ERROR: open_fifo_server: socketpair failed: %s\n",
				strerror(errno));
			return -1;
	}
#endif
	process_no++;
	fifo_pid=fork();
	if (fifo_pid<0) {
		LOG(L_ERR, "ERROR: open_fifo_server: failure to fork: %s\n",
			strerror(errno));
		return -1;
	}
	if (fifo_pid==0) { /* child == FIFO server */
		LOG(L_INFO, "INFO: fifo process starting: %d\n", getpid());
		/* call per-child module initialization too -- some
		   FIFO commands may need it
		*/
#ifdef USE_TCP
		close(sockfd[0]);
		unix_tcp_sock=sockfd[1];
#endif
		if (init_child(PROC_FIFO) < 0 ) {
			LOG(L_ERR, "ERROR: open_uac_fifo: init_child failed\n");
			return -1;
		}
		fifo_read=open(fifo, O_RDONLY, 0);
		if (fifo_read<0) {
			LOG(L_ERR, "ERROR: open_uac_fifo: fifo_read did not open: %s\n",
				strerror(errno));
			return -1;
		}
		fifo_stream=fdopen(fifo_read, "r"	);
		if (fifo_stream==NULL) {
			LOG(L_ERR, "SER: open_uac_fifo: fdopen failed: %s\n",
				strerror(errno));
			return -1;
		}
		/* a real server doesn't die if writing to reply fifo fails */
		signal(SIGPIPE, SIG_IGN);
		LOG(L_INFO, "SER: open_uac_fifo: fifo server up at %s...\n",
			fifo);
		fifo_server( fifo_stream ); /* never retruns */
	}
	/* dad process */
	pt[process_no].pid=fifo_pid;
	strncpy(pt[process_no].desc, "fifo server", MAX_PT_DESC );
#ifdef USE_TCP
	close(sockfd[1]);
	pt[process_no].unix_sock=sockfd[0];
	pt[process_no].idx=-1; /* this is not "tcp" process*/
#endif
	/* make sure the read fifo will not close */
	fifo_write=open(fifo, O_WRONLY, 0);
	if (fifo_write<0) {
		LOG(L_ERR, "SER: open_uac_fifo: fifo_write did not open: %s\n",
			strerror(errno));
		return -1;
	}
	return 1;
}
예제 #23
0
파일: main.c 프로젝트: Parantido/opensips
/**
 * Main loop, forks the children, bind to addresses,
 * handle signals.
 * \return don't return on sucess, -1 on error
 */
static int main_loop(void)
{
	static int chd_rank;
	int* startup_done = NULL;

	chd_rank=0;

	if (start_module_procs()!=0) {
		LM_ERR("failed to fork module processes\n");
		goto error;
	}

	if(startup_rlist.a) {/* if a startup route was defined */
		startup_done = (int*)shm_malloc(sizeof(int));
		if(startup_done == NULL) {
			LM_ERR("No more shared memory\n");
			goto error;
		}
		*startup_done = 0;
	}

	/* fork for the timer process*/
	if (start_timer_processes()!=0) {
		LM_CRIT("cannot start timer process(es)\n");
		goto error;
	}

	/* fork all processes required by UDP network layer */
	if (udp_start_processes( &chd_rank, startup_done)<0) {
		LM_CRIT("cannot start TCP processes\n");
		goto error;
	}

	/* fork all processes required by TCP network layer */
	if (tcp_start_processes( &chd_rank, startup_done)<0) {
		LM_CRIT("cannot start TCP processes\n");
		goto error;
	}

	/* this is the main process -> it shouldn't send anything */
	bind_address=0;

	if (startup_done) {
		if (*startup_done==0)
			LM_CRIT("BUG: startup route defined, but not run :( \n");
		shm_free(startup_done);
	}

	/* main process left */
	is_main=1;
	set_proc_attrs("attendant");

	if (init_child(PROC_MAIN) < 0) {
		LM_ERR("error in init_child for PROC_MAIN\n");
		report_failure_status();
		goto error;
	}

	report_conditional_status( (!no_daemon_mode), 0);

	for(;;){
			handle_sigs();
			pause();
	}

	/*return 0; */
error:
	is_main=1;  /* if we are here, we are the "main process",
				  any forked children should exit with exit(-1) and not
				  ever use return */
	report_failure_status();
	return -1;

}
예제 #24
0
파일: main.c 프로젝트: zhangzheyuk/opensips
/**
 * Main loop, forks the children, bind to addresses,
 * handle signals.
 * \return don't return on sucess, -1 on error
 */
static int main_loop(void)
{
	static int chd_rank;
	int  i,rc;
	pid_t pid;
	struct socket_info* si;
	int* startup_done = NULL;
	stat_var *load_p = NULL;

	chd_rank=0;

	if (init_debug() != 0) {
		LM_ERR("failed to init logging levels\n");
		goto error;
	}

	if (dont_fork){

		if (create_status_pipe() < 0) {
			LM_ERR("failed to create status pipe");
			goto error;
		}

		if (udp_listen==0){
			LM_ERR("no fork mode requires at least one"
					" udp listen address, exiting...\n");
			goto error;
		}
		/* only one address, we ignore all the others */
		if (udp_init(udp_listen)==-1) goto error;
		bind_address=udp_listen;
		sendipv4=bind_address;
		sendipv6=bind_address; /*FIXME*/
		if (udp_listen->next){
			LM_WARN("using only the first listen address (no fork)\n");
		}

		/* try to drop privileges */
		if (do_suid(uid, gid)==-1)
			goto error;

		if (start_module_procs()!=0) {
			LM_ERR("failed to fork module processes\n");
			goto error;
		}

		/* we need another process to act as the timer*/
		if (start_timer_processes()!=0) {
			LM_CRIT("cannot start timer process(es)\n");
			goto error;
		}

		/* main process, receive loop */
		set_proc_attrs("stand-alone SIP receiver %.*s",
			 bind_address->sock_str.len, bind_address->sock_str.s );

		/* We will call child_init even if we
		 * do not fork - and it will be called with rank 1 because
		 * in fact we behave like a child, not like main process */
		if (init_child(1) < 0) {
			LM_ERR("init_child failed in don't fork\n");
			goto error;
		}

		if (startup_rlist.a)
			run_startup_route();

		is_main=1;

		if (register_udp_load_stat(&udp_listen->sock_str,
		&pt[process_no].load, 1)!=0) {
			LM_ERR("failed to init udp load statistics\n");
			goto error;
		}

		clean_write_pipeend();
		LM_DBG("waiting for status code from children\n");
		rc = wait_for_all_children();
		if (rc < 0) {
			LM_ERR("failed to succesfully init children\n");
			return rc;
		}

		return udp_rcv_loop();
	} else {  /* don't fork */

		for(si=udp_listen;si;si=si->next){
			/* create the listening socket (for each address)*/
			/* udp */
			if (udp_init(si)==-1) goto error;
			/* get first ipv4/ipv6 socket*/
			if ((si->address.af==AF_INET)&&
					((sendipv4==0)||(sendipv4->flags&SI_IS_LO)))
				sendipv4=si;
			#ifdef USE_IPV6
			if((sendipv6==0)&&(si->address.af==AF_INET6))
				sendipv6=si;
			#endif
		}
		#ifdef USE_TCP
		if (!tcp_disable){
			for(si=tcp_listen; si; si=si->next){
				/* same thing for tcp */
				if (tcp_init(si)==-1)  goto error;
				/* get first ipv4/ipv6 socket*/
				if ((si->address.af==AF_INET)&
						((sendipv4_tcp==0)||(sendipv4_tcp->flags&SI_IS_LO)))
					sendipv4_tcp=si;
				#ifdef USE_IPV6
				if((sendipv6_tcp==0)&&(si->address.af==AF_INET6))
					sendipv6_tcp=si;
				#endif
			}
		}
		#ifdef USE_TLS
		if (!tls_disable){
			for(si=tls_listen; si; si=si->next){
				/* same as for tcp*/
				if (tls_init(si)==-1)  goto error;
				/* get first ipv4/ipv6 socket*/
				if ((si->address.af==AF_INET)&&
						((sendipv4_tls==0)||(sendipv4_tls->flags&SI_IS_LO)))
					sendipv4_tls=si;
				#ifdef USE_IPV6
				if((sendipv6_tls==0)&&(si->address.af==AF_INET6))
					sendipv6_tls=si;
				#endif
			}
		}
		#endif /* USE_TLS */
		#endif /* USE_TCP */
		#ifdef USE_SCTP
		if (!sctp_disable){
			for(si=sctp_listen; si; si=si->next){
				/* same thing for sctp */
				if (sctp_server_init(si)==-1)  goto error;
				/* get first ipv4/ipv6 socket*/
				if ((si->address.af==AF_INET)&&
						((sendipv4_sctp==0)||(sendipv4_sctp->flags&SI_IS_LO)))
					sendipv4_sctp=si;
			#ifdef USE_IPV6
				if((sendipv6_sctp==0)&&(si->address.af==AF_INET6))
					sendipv6_sctp=si;
			#endif
			}
		}
		#endif /* USE_SCTP */

		/* all processes should have access to all the sockets (for sending)
		 * so we open all first*/
		if (do_suid(uid, gid)==-1) goto error; /* try to drop privileges */

		if (start_module_procs()!=0) {
			LM_ERR("failed to fork module processes\n");
			goto error;
		}

		if(startup_rlist.a) {/* if a startup route was defined */
			startup_done = (int*)shm_malloc(sizeof(int));
			if(startup_done == NULL) {
				LM_ERR("No more shared memory\n");
				goto error;
			}
			*startup_done = 0;
		}

		if (fix_socket_list(&bin) != 0) {
			LM_ERR("failed to initialize binary interface socket list!\n");
			goto error;
		}

		/* OpenSIPS <--> OpenSIPS communication interface */
		if (bin && start_bin_receivers() != 0) {
			LM_CRIT("cannot start binary interface receiver processes!\n");
			goto error;
		}

		/* udp processes */
		for(si=udp_listen; si; si=si->next){

			if(register_udp_load_stat(&si->sock_str,&load_p,si->children)!=0){
				LM_ERR("failed to init load statistics\n");
				goto error;
			}

			for(i=0;i<si->children;i++){
				chd_rank++;
				if ( (pid=internal_fork( "UDP receiver"))<0 ) {
					LM_CRIT("cannot fork UDP process\n");
					goto error;
				} else {
					if (pid==0) {
						/* new UDP process */
						/* set a more detailed description */
						set_proc_attrs("SIP receiver %.*s ",
							si->sock_str.len, si->sock_str.s);
						bind_address=si; /* shortcut */
						if (init_child(chd_rank) < 0) {
							LM_ERR("init_child failed for UDP listener\n");
							if (send_status_code(-1) < 0)
								LM_ERR("failed to send status code\n");
							clean_write_pipeend();
							if (chd_rank == 1 && startup_done)
								*startup_done = -1;
							exit(-1);
						}

						/* first UDP proc runs statup_route (if defined) */
						if(chd_rank == 1 && startup_done!=NULL) {
							LM_DBG("runing startup for first UDP\n");
							if(run_startup_route()< 0) {
								if (send_status_code(-1) < 0)
									LM_ERR("failed to send status code\n");
								clean_write_pipeend();
								*startup_done = -1;
								LM_ERR("Startup route processing failed\n");
								exit(-1);
							}
							*startup_done = 1;
						}

						if (!no_daemon_mode && send_status_code(0) < 0)
							LM_ERR("failed to send status code\n");
						clean_write_pipeend();


						/* all UDP listeners on same interface
						 * have same SHM load pointer */
						pt[process_no].load = load_p;
						udp_rcv_loop();
						exit(-1);
					}
					else {
						/* wait for first proc to finish the startup route */
						if(chd_rank == 1 && startup_done!=NULL)
							while( !(*startup_done) ) {usleep(5);handle_sigs();}
					}
				}
			}
			/*parent*/
			/*close(udp_sock)*/; /*if it's closed=>sendto invalid fd errors?*/
		}
	}

	#ifdef USE_SCTP
	if(!sctp_disable){
		for(si=sctp_listen; si; si=si->next){
			for(i=0;i<si->children;i++){
				chd_rank++;
				if ( (pid=internal_fork( "SCTP receiver"))<0 ) {
					LM_CRIT("cannot fork SCTP process\n");
					goto error;
				} else if (pid==0){
					/* new SCTP process */
					/* set a more detailed description */
					set_proc_attrs("SIP receiver %.*s ",
						si->sock_str.len, si->sock_str.s);
					bind_address=si; /* shortcut */
					if (init_child(chd_rank) < 0) {
						LM_ERR("init_child failed\n");
						if (send_status_code(-1) < 0)
							LM_ERR("failed to send status code\n");
						clean_write_pipeend();
						if( (si==sctp_listen && i==0) && startup_done)
							*startup_done = -1;
						exit(-1);
					}

					/* was startup route executed so far ? if not, run it only by the
					 * first SCTP proc (first proc from first interface) */
					if( (si==sctp_listen && i==0) && startup_done!=NULL && *startup_done==0) {
						LM_DBG("runing startup for first SCTP\n");
						if(run_startup_route()< 0) {
							LM_ERR("Startup route processing failed\n");
							if (send_status_code(-1) < 0)
								LM_ERR("failed to send status code\n");
							clean_write_pipeend();
							*startup_done = -1;
							exit(-1);
						}
						*startup_done = 1;
					}

					if (!no_daemon_mode && send_status_code(0) < 0)
						LM_ERR("failed to send status code\n");
					clean_write_pipeend();

					sctp_server_rcv_loop();
					exit(-1);
				} else {
					/* wait for first proc to finish the startup route */
					if( (si==sctp_listen && i==0) && startup_done!=NULL)
						while( !(*startup_done) ) {usleep(5);handle_sigs();}
				}
			}
		}
	}
	#endif /* USE_SCTP */

	/* this is the main process -> it shouldn't send anything */
	bind_address=0;

	/* fork for the timer process*/
	if (start_timer_processes()!=0) {
		LM_CRIT("cannot start timer process(es)\n");
		goto error;
	}

	#ifdef USE_TCP
	if (!tcp_disable){
		/* start tcp  & tls receivers */
		if (tcp_init_children(&chd_rank, startup_done)<0) goto error;
		/* wait for the startup route to be executed */
		if( startup_done!=NULL)
			while( !(*startup_done) ) {usleep(5);handle_sigs();}
		/* start tcp+tls master proc */
		if ( (pid=internal_fork( "TCP main"))<0 ) {
			LM_CRIT("cannot fork tcp main process\n");
			goto error;
		}else if (pid==0){
			/* child */
			/* close the TCP inter-process sockets */
			close(unix_tcp_sock);
			unix_tcp_sock = -1;
			close(pt[process_no].unix_sock);
			pt[process_no].unix_sock = -1;
			/* init modules */
			if (init_child(PROC_TCP_MAIN) < 0) {
				LM_ERR("error in init_child for tcp main\n");
				if (send_status_code(-1) < 0)
					LM_ERR("failed to send status code\n");
				clean_write_pipeend();

				exit(-1);
			}

			if (!no_daemon_mode && send_status_code(0) < 0)
				LM_ERR("failed to send status code\n");
			clean_write_pipeend();

			tcp_main_loop();
			exit(-1);
		}
	}
	#endif

	if (startup_done) {
		if (*startup_done==0)
			LM_CRIT("BUG: startup route defined, but not run :( \n");
		shm_free(startup_done);
	}

	/* main process left */
	is_main=1;
	set_proc_attrs("attendant");

	if (init_child(PROC_MAIN) < 0) {
		if (send_status_code(-1) < 0)
			LM_ERR("failed to send status code\n");
		clean_write_pipeend();
		LM_ERR("error in init_child for PROC_MAIN\n");
		goto error;
	}

	if (!no_daemon_mode && send_status_code(0) < 0)
		LM_ERR("failed to send status code\n");
	clean_write_pipeend();

	for(;;){
			handle_sigs();
			pause();
	}

	/*return 0; */
error:
	is_main=1;  /* if we are here, we are the "main process",
				  any forked children should exit with exit(-1) and not
				  ever use return */
	if (!dont_fork && send_status_code(-1) < 0)
		LM_ERR("failed to send status code\n");
	clean_write_pipeend();

	return -1;

}
예제 #25
0
/**
 * Main loop, forks the children, bind to addresses,
 * handle signals.
 * \return don't return on sucess, -1 on error
 */
static int main_loop(void)
{
    static int chd_rank;
    int* startup_done = NULL;

    chd_rank=0;

    if (init_debug() != 0) {
        LM_ERR("failed to init logging levels\n");
        goto error;
    }

    if (dont_fork) {

        if (create_status_pipe() < 0) {
            LM_ERR("failed to create status pipe\n");
            goto error;
        }

        if (udp_init_nofork() < 0) {
            LM_ERR("failed to init UDP for no fork mode\n");
            goto error;
        }

        /* try to drop privileges */
        if (do_suid(uid, gid)==-1)
            goto error;

        if (start_module_procs()!=0) {
            LM_ERR("failed to fork module processes\n");
            goto error;
        }

        /* we need another process to act as the timer*/
        if (start_timer_processes()!=0) {
            LM_CRIT("cannot start timer process(es)\n");
            goto error;
        }

        is_main=1;

        udp_start_nofork();
        /* udp_start_nofork() returns only if error */

        /* in case of failed startup, behave as "attendant" to trigger
         * proper cleanup sequance (and proper signal handler !!!).
         * So, reset the dont_fork (as it will force inline signal handling)*/
        dont_fork = 0;
        return -1;

    } else {  /* don't fork */

        if (trans_init_all_listeners()<0) {
            LM_ERR("failed to init all SIP listeners, aborting\n");
            goto error;
        }

        /* all processes should have access to all the sockets (for sending)
         * so we open all first*/
        if (do_suid(uid, gid)==-1) goto error; /* try to drop privileges */

        if (start_module_procs()!=0) {
            LM_ERR("failed to fork module processes\n");
            goto error;
        }

        if(startup_rlist.a) {/* if a startup route was defined */
            startup_done = (int*)shm_malloc(sizeof(int));
            if(startup_done == NULL) {
                LM_ERR("No more shared memory\n");
                goto error;
            }
            *startup_done = 0;
        }

        if (fix_socket_list(&bin) != 0) {
            LM_ERR("failed to initialize binary interface socket list!\n");
            goto error;
        }

        /* OpenSIPS <--> OpenSIPS communication interface */
        if (bin && start_bin_receivers() != 0) {
            LM_CRIT("cannot start binary interface receiver processes!\n");
            goto error;
        }

        /* fork for the timer process*/
        if (start_timer_processes()!=0) {
            LM_CRIT("cannot start timer process(es)\n");
            goto error;
        }

        /* fork all processes required by UDP network layer */
        if (udp_start_processes( &chd_rank, startup_done)<0) {
            LM_CRIT("cannot start TCP processes\n");
            goto error;
        }

        /* fork all processes required by TCP network layer */
        if (tcp_start_processes( &chd_rank, startup_done)<0) {
            LM_CRIT("cannot start TCP processes\n");
            goto error;
        }
    }

    /* this is the main process -> it shouldn't send anything */
    bind_address=0;

    if (startup_done) {
        if (*startup_done==0)
            LM_CRIT("BUG: startup route defined, but not run :( \n");
        shm_free(startup_done);
    }

    /* main process left */
    is_main=1;
    set_proc_attrs("attendant");

    if (init_child(PROC_MAIN) < 0) {
        LM_ERR("error in init_child for PROC_MAIN\n");
        report_failure_status();
        goto error;
    }

    report_conditional_status( (!no_daemon_mode), 0);

    for(;;) {
        handle_sigs();
        pause();
    }

    /*return 0; */
error:
    is_main=1;  /* if we are here, we are the "main process",
				  any forked children should exit with exit(-1) and not
				  ever use return */
    report_conditional_status( (!dont_fork), -1);
    return -1;

}
예제 #26
0
/**
 * Forks a new process.
 * @param child_id - rank, if equal to PROC_NOCHLDINIT init_child will not be
 *                   called for the new forked process (see sr_module.h)
 * @param desc - text description for the process table
 * @param make_sock - if to create a unix socket pair for it
 * @returns the pid of the new process
 */
int fork_process(int child_id, char *desc, int make_sock)
{
	int pid, child_process_no;
	int ret;
	unsigned int new_seed1;
	unsigned int new_seed2;
#ifdef USE_TCP
	int sockfd[2];
#endif

	if(unlikely(fork_delay>0))
		sleep_us(fork_delay);

	ret=-1;
	#ifdef USE_TCP
		sockfd[0]=sockfd[1]=-1;
		if(make_sock && !tcp_disable){
			if (!is_main){
				LM_CRIT("called from a non "
						"\"main\" process! If forking from a module's "
						"child_init() fork only if rank==PROC_MAIN or"
						" give up tcp send support (use 0 for make_sock)\n");
				goto error;
			}
			if (tcp_main_pid){
				LM_CRIT("called, but tcp main is already started\n");
				goto error;
			}
			if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd)<0){
				LM_ERR("socketpair failed: %s\n",
							strerror(errno));
				goto error;
			}
		}
	#endif
	lock_get(process_lock);
	if (*process_count>=estimated_proc_no) {
		LM_CRIT("Process limit of %d exceeded. Will simulate fork fail.\n",
				estimated_proc_no);
		lock_release(process_lock);
		goto error;
	}

	child_process_no = *process_count;
	new_seed1=kam_rand();
	new_seed2=random();
	pid = fork();
	if (pid<0) {
		lock_release(process_lock);
		ret=pid;
		goto error;
	}else if (pid==0){
		/* child */
		is_main=0; /* a forked process cannot be the "main" one */
		process_no=child_process_no;
		daemon_status_on_fork_cleanup();
		/* close tcp unix sockets if this is not tcp main */
#ifdef USE_TCP
		close_extra_socks(child_id, process_no);
#endif /* USE_TCP */
		kam_srand(new_seed1);
		fastrand_seed(kam_rand());
		srandom(new_seed2+time(0));
		shm_malloc_on_fork();
#ifdef PROFILING
		monstartup((u_long) &_start, (u_long) &etext);
#endif
#ifdef FORK_DONT_WAIT
		/* record pid twice to avoid the child using it, before
		 * parent gets a chance to set it*/
		pt[process_no].pid=getpid();
#else
		/* wait for parent to get out of critical zone.
		 * this is actually relevant as the parent updates
		 * the pt & process_count. */
		lock_get(process_lock);
		lock_release(process_lock);
#endif
		#ifdef USE_TCP
			if (make_sock && !tcp_disable){
				close(sockfd[0]);
				unix_tcp_sock=sockfd[1];
			}
		#endif
		if ((child_id!=PROC_NOCHLDINIT) && (init_child(child_id) < 0)) {
			LM_ERR("init_child failed for process %d, pid %d, \"%s\"\n",
					process_no, pt[process_no].pid, pt[process_no].desc);
			return -1;
		}
		return pid;
	} else {
		/* parent */
		(*process_count)++;
#ifdef FORK_DONT_WAIT
		lock_release(process_lock);
#endif
		/* add the process to the list in shm */
		pt[child_process_no].pid=pid;
		if (desc){
			strncpy(pt[child_process_no].desc, desc, MAX_PT_DESC-1);
		}
		#ifdef USE_TCP
			if (make_sock && !tcp_disable){
				close(sockfd[1]);
				pt[child_process_no].unix_sock=sockfd[0];
				pt[child_process_no].idx=-1; /* this is not a "tcp" process*/
			}
		#endif
#ifdef FORK_DONT_WAIT
#else
		lock_release(process_lock);
#endif
		ret=pid;
		goto end;
	}
error:
#ifdef USE_TCP
	if (sockfd[0]!=-1) close(sockfd[0]);
	if (sockfd[1]!=-1) close(sockfd[1]);
#endif
end:
	return ret;
}
예제 #27
0
파일: main.c 프로젝트: nloopa/trinity
static void fork_children(void)
{
	int pidslot;
	static char childname[17];

	/* Generate children*/

	while (shm->running_childs < shm->max_children) {
		int pid = 0;
		int fd;

		if (shm->spawn_no_more == TRUE)
			return;

		/* a new child means a new seed, or the new child
		 * will do the same syscalls as the one in the pidslot it's replacing.
		 * (special case startup, or we reseed unnecessarily)
		 */
		if (shm->ready == TRUE)
			reseed();

		/* Find a space for it in the pid map */
		pidslot = find_pid_slot(EMPTY_PIDSLOT);
		if (pidslot == PIDSLOT_NOT_FOUND) {
			outputerr("## Pid map was full!\n");
			dump_pid_slots();
			exit(EXIT_FAILURE);
		}

		if (logging == TRUE) {
			fd = fileno(shm->logfiles[pidslot]);
			if (ftruncate(fd, 0) == 0)
				lseek(fd, 0, SEEK_SET);
		}

		(void)alarm(0);
		fflush(stdout);
		pid = fork();
		if (pid != 0)
			shm->pids[pidslot] = pid;
		else {
			/* Child process. */
			int ret = 0;

			mask_signals_child();

			memset(childname, 0, sizeof(childname));
			sprintf(childname, "trinity-child%d", pidslot);
			prctl(PR_SET_NAME, (unsigned long) &childname);

			oom_score_adj(500);

			/* Wait for parent to set our pidslot */
			while (shm->pids[pidslot] != getpid()) {
				/* Make sure parent is actually alive to wait for us. */
				ret = pid_alive(shm->mainpid);
				if (ret != 0) {
					shm->exit_reason = EXIT_SHM_CORRUPTION;
					outputerr(BUGTXT "parent (%d) went away!\n", shm->mainpid);
					sleep(20000);
				}
			}

			/* Wait for all the children to start up. */
			while (shm->ready == FALSE)
				sleep(1);

			init_child(pidslot);

			ret = child_process(pidslot);

			output(1, "child exiting.\n");

			_exit(ret);
		}
		shm->running_childs++;
		debugf("Created child %d in pidslot %d [total:%d/%d]\n",
			shm->pids[pidslot], pidslot,
			shm->running_childs, shm->max_children);

		if (shm->exit_reason != STILL_RUNNING)
			return;

	}
	shm->ready = TRUE;

	debugf("created enough children\n");
}
예제 #28
0
int fork_tcp_process(int child_id, char *desc, int r, int *reader_fd_1)
{
	int pid, child_process_no;
	int sockfd[2];
	int reader_fd[2]; /* for comm. with the tcp children read  */
	int ret;
	int i;
	unsigned int new_seed1;
	unsigned int new_seed2;

	/* init */
	sockfd[0]=sockfd[1]=-1;
	reader_fd[0]=reader_fd[1]=-1;
	ret=-1;

	if (!is_main){
		LM_CRIT("called from a non \"main\" process\n");
		goto error;
	}
	if (tcp_main_pid){
		LM_CRIT("called _after_ starting tcp main\n");
		goto error;
	}
	if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd)<0){
		LM_ERR("socketpair failed: %s\n", strerror(errno));
		goto error;
	}
	if (socketpair(AF_UNIX, SOCK_STREAM, 0, reader_fd)<0){
		LM_ERR("socketpair failed: %s\n", strerror(errno));
		goto error;
	}
	if (tcp_fix_child_sockets(reader_fd)<0){
		LM_ERR("failed to set non blocking on child sockets\n");
		/* continue, it's not critical (it will go slower under
		 * very high connection rates) */
	}
	lock_get(process_lock);
	/* set the local process_no */
	if (*process_count>=estimated_proc_no) {
		LM_CRIT("Process limit of %d exceeded. Simulating fork fail\n",
					estimated_proc_no);
		lock_release(process_lock);
		goto error;
	}

	child_process_no = *process_count;
	new_seed1=kam_rand();
	new_seed2=random();
	pid = fork();
	if (pid<0) {
		lock_release(process_lock);
		ret=pid;
		goto end;
	}
	if (pid==0){
		is_main=0; /* a forked process cannot be the "main" one */
		process_no=child_process_no;
		/* close unneeded unix sockets */
		close_extra_socks(child_id, process_no);
		/* same for unneeded tcp_children <-> tcp_main unix socks */
		for (i=0; i<r; i++){
			if (tcp_children[i].unix_sock>=0){
				close(tcp_children[i].unix_sock);
				/* tcp_children is per process, so it's safe to change
				 * the unix_sock to -1 */
				tcp_children[i].unix_sock=-1;
			}
		}
		daemon_status_on_fork_cleanup();
		kam_srand(new_seed1);
		fastrand_seed(kam_rand());
		srandom(new_seed2+time(0));
		shm_malloc_on_fork();
#ifdef PROFILING
		monstartup((u_long) &_start, (u_long) &etext);
#endif
#ifdef FORK_DONT_WAIT
		/* record pid twice to avoid the child using it, before
-		 * parent gets a chance to set it*/
		pt[process_no].pid=getpid();
#else
		/* wait for parent to get out of critical zone */
		lock_get(process_lock);
		lock_release(process_lock);
#endif
		close(sockfd[0]);
		unix_tcp_sock=sockfd[1];
		close(reader_fd[0]);
		if (reader_fd_1) *reader_fd_1=reader_fd[1];
		if ((child_id!=PROC_NOCHLDINIT) && (init_child(child_id) < 0)) {
			LM_ERR("init_child failed for process %d, pid %d, \"%s\"\n",
				process_no, pt[process_no].pid, pt[process_no].desc);
			return -1;
		}
		return pid;
	} else {
		/* parent */
		(*process_count)++;
#ifdef FORK_DONT_WAIT
		lock_release(process_lock);
#endif
		/* add the process to the list in shm */
		pt[child_process_no].pid=pid;
		pt[child_process_no].unix_sock=sockfd[0];
		pt[child_process_no].idx=r;
		if (desc){
			snprintf(pt[child_process_no].desc, MAX_PT_DESC, "%s child=%d",
						desc, r);
		}
#ifdef FORK_DONT_WAIT
#else
		lock_release(process_lock);
#endif

		close(sockfd[1]);
		close(reader_fd[1]);

		tcp_children[r].pid=pid;
		tcp_children[r].proc_no=child_process_no;
		tcp_children[r].busy=0;
		tcp_children[r].n_reqs=0;
		tcp_children[r].unix_sock=reader_fd[0];

		ret=pid;
		goto end;
	}
error:
	if (sockfd[0]!=-1) close(sockfd[0]);
	if (sockfd[1]!=-1) close(sockfd[1]);
	if (reader_fd[0]!=-1) close(reader_fd[0]);
	if (reader_fd[1]!=-1) close(reader_fd[1]);
end:
	return ret;
}
예제 #29
0
/**
 * Main loop, forks the children, bind to addresses,
 * handle signals.
 * \return don't return on sucess, -1 on error
 */
static int main_loop(void)
{
	static int chd_rank;
	int  i;
	pid_t pid;
	struct socket_info* si;
	int* startup_done = NULL;
	atomic_t *load_p;

	chd_rank=0;

	if (dont_fork){
		if (udp_listen==0){
			LM_ERR("no fork mode requires at least one"
					" udp listen address, exiting...\n");
			goto error;
		}
		/* only one address, we ignore all the others */
		if (udp_init(udp_listen)==-1) goto error;
		bind_address=udp_listen;
		sendipv4=bind_address;
		sendipv6=bind_address; /*FIXME*/
		if (udp_listen->next){
			LM_WARN("using only the first listen address (no fork)\n");
		}

		/* try to drop privileges */
		if (do_suid(uid, gid)==-1)
			goto error;

		if (start_module_procs()!=0) {
			LM_ERR("failed to fork module processes\n");
			goto error;
		}

		/* we need another process to act as the timer*/
		if (start_timer_processes()!=0) {
			LM_CRIT("cannot start timer process(es)\n");
			goto error;
		}

		/* main process, receive loop */
		set_proc_attrs("stand-alone SIP receiver %.*s", 
			 bind_address->sock_str.len, bind_address->sock_str.s );

		/* We will call child_init even if we
		 * do not fork - and it will be called with rank 1 because
		 * in fact we behave like a child, not like main process */
		if (init_child(1) < 0) {
			LM_ERR("init_child failed in don't fork\n");
			goto error;
		}

		if (startup_rlist.a)
			run_startup_route();

		is_main=1;
		load_p = shm_malloc(sizeof(atomic_t));
		if (!load_p) {
		/* highly improbable */
			LM_ERR("no more shm\n");
			goto error;
		}
		memset(load_p,0,sizeof(atomic_t));
		pt[process_no].load = load_p;

		register_udp_load_stat(&udp_listen->sock_str,load_p);
		return udp_rcv_loop();
	} else {  /* don't fork */

		for(si=udp_listen;si;si=si->next){
			/* create the listening socket (for each address)*/
			/* udp */
			if (udp_init(si)==-1) goto error;
			/* get first ipv4/ipv6 socket*/
			if ((si->address.af==AF_INET)&&
					((sendipv4==0)||(sendipv4->flags&SI_IS_LO)))
				sendipv4=si;
			#ifdef USE_IPV6
			if((sendipv6==0)&&(si->address.af==AF_INET6))
				sendipv6=si;
			#endif
		}
		#ifdef USE_TCP
		if (!tcp_disable){
			for(si=tcp_listen; si; si=si->next){
				/* same thing for tcp */
				if (tcp_init(si)==-1)  goto error;
				/* get first ipv4/ipv6 socket*/
				if ((si->address.af==AF_INET)&&
						((sendipv4_tcp==0)||(sendipv4_tcp->flags&SI_IS_LO)))
					sendipv4_tcp=si;
				#ifdef USE_IPV6
				if((sendipv6_tcp==0)&&(si->address.af==AF_INET6))
					sendipv6_tcp=si;
				#endif
			}
		}
		#ifdef USE_TLS
		if (!tls_disable){
			for(si=tls_listen; si; si=si->next){
				/* same as for tcp*/
				if (tls_init(si)==-1)  goto error;
				/* get first ipv4/ipv6 socket*/
				if ((si->address.af==AF_INET)&&
						((sendipv4_tls==0)||(sendipv4_tls->flags&SI_IS_LO)))
					sendipv4_tls=si;
				#ifdef USE_IPV6
				if((sendipv6_tls==0)&&(si->address.af==AF_INET6))
					sendipv6_tls=si;
				#endif
			}
		}
		#endif /* USE_TLS */
		#endif /* USE_TCP */
		#ifdef USE_SCTP
		if (!sctp_disable){
			for(si=sctp_listen; si; si=si->next){
				/* same thing for sctp */
				if (sctp_server_init(si)==-1)  goto error;
				/* get first ipv4/ipv6 socket*/
				if ((si->address.af==AF_INET)&&
						((sendipv4_sctp==0)||(sendipv4_sctp->flags&SI_IS_LO)))
					sendipv4_sctp=si;
			#ifdef USE_IPV6
				if((sendipv6_sctp==0)&&(si->address.af==AF_INET6))
					sendipv6_sctp=si;
			#endif
			}
		}
		#endif /* USE_SCTP */

		/* all processes should have access to all the sockets (for sending)
		 * so we open all first*/
		if (do_suid(uid, gid)==-1) goto error; /* try to drop privileges */

		if (start_module_procs()!=0) {
			LM_ERR("failed to fork module processes\n");
			goto error;
		}

		if(startup_rlist.a) {/* if a startup route was defined */
			startup_done = (int*)shm_malloc(sizeof(int));
			if(startup_done == NULL)
			{
				LM_ERR("No more shared memory\n");
				goto error;
			}
			*startup_done = 0;
		}

		/* udp processes */
		for(si=udp_listen; si; si=si->next){
			load_p = shm_malloc(sizeof(atomic_t));
			if (!load_p) {
			/* highly improbable */
				LM_ERR("no more shm\n");
				goto error;
			}
			memset(load_p,0,sizeof(atomic_t));
			register_udp_load_stat(&si->sock_str,load_p);

			for(i=0;i<children_no;i++){
				chd_rank++;
				if ( (pid=internal_fork( "UDP receiver"))<0 ) {
					LM_CRIT("cannot fork UDP process\n");
					goto error;
				} else {
					if (pid==0) {
						/* new UDP process */
						/* set a more detailed description */
						set_proc_attrs("SIP receiver %.*s ",
							si->sock_str.len, si->sock_str.s);
						bind_address=si; /* shortcut */
						if (init_child(chd_rank) < 0) {
							LM_ERR("init_child failed for UDP listener\n");
							exit(-1);
						}

						if(chd_rank == 1 && startup_rlist.a) {
							if(run_startup_route()< 0) {
								LM_ERR("Startup route processing failed\n");
								exit(-1);
							}
							*startup_done = 1;
						}

						/* all UDP listeners on same interface
						 * have same SHM load pointer */
						pt[process_no].load = load_p;
						udp_rcv_loop();
						exit(-1);
					}
					else {
						/* if the first process that runs startup_route*/
						if(chd_rank == 1 && startup_rlist.a) {
							while(!startup_done) {
								usleep(5);
							}
							shm_free(startup_done);
						}
					}
				}
			}
			/*parent*/
			/*close(udp_sock)*/; /*if it's closed=>sendto invalid fd errors?*/
		}
	}

	#ifdef USE_SCTP
	if(!sctp_disable){
		for(si=sctp_listen; si; si=si->next){
			for(i=0;i<children_no;i++){
				chd_rank++;
				if ( (pid=internal_fork( "SCTP receiver"))<0 ) {
					LM_CRIT("cannot fork SCTP process\n");
					goto error;
				} else if (pid==0){
					/* new SCTP process */
					/* set a more detailed description */
					set_proc_attrs("SIP receiver %.*s ",
						si->sock_str.len, si->sock_str.s);
					bind_address=si; /* shortcut */
					if (init_child(chd_rank) < 0) {
						LM_ERR("init_child failed\n");
						exit(-1);
					}
					sctp_server_rcv_loop();
					exit(-1);
				}
			}
		}
	}
	#endif /* USE_SCTP */

	/* this is the main process -> it shouldn't send anything */
	bind_address=0;

	/* fork for the timer process*/
	if (start_timer_processes()!=0) {
		LM_CRIT("cannot start timer process(es)\n");
		goto error;
	}

	#ifdef USE_TCP
	if (!tcp_disable){
		/* start tcp  & tls receivers */
		if (tcp_init_children(&chd_rank)<0) goto error;
		/* start tcp+tls master proc */
		if ( (pid=internal_fork( "TCP main"))<0 ) {
			LM_CRIT("cannot fork tcp main process\n");
			goto error;
		}else if (pid==0){
			/* child */
			/* close the TCP inter-process sockets */
			close(unix_tcp_sock);
			unix_tcp_sock = -1;
			close(pt[process_no].unix_sock);
			pt[process_no].unix_sock = -1;
			/* init modules */
			if (init_child(PROC_TCP_MAIN) < 0) {
				LM_ERR("error in init_child for tcp main\n");
				exit(-1);
			}
			tcp_main_loop();
			exit(-1);
		}
	}
	#endif

	/* main process left */
	is_main=1;
	set_proc_attrs("attendant");

	if (init_child(PROC_MAIN) < 0) {
		LM_ERR("error in init_child for PROC_MAIN\n");
		goto error;
	}

	for(;;){
			handle_sigs();
			pause();
	}

	/*return 0; */
error:
	is_main=1;  /* if we are here, we are the "main process",
				  any forked children should exit with exit(-1) and not
				  ever use return */
	return -1;

}
예제 #30
0
파일: ViewOrb.c 프로젝트: xomachine/gabedit
int view_orb(GtkWidget* Parent,int argc, char **argv)
{
	GtkWidget* vboxwin;
	GtkWidget* hboxwin;
	GtkWidget* handleBoxColorMapGrid;
	GtkWidget* handleBoxColorMapContours;
	GtkWidget* handleBoxColorMapPlanesMapped;

	static gboolean first = TRUE;


	init_dipole();
	if(!first)
	{
		if(PrincipalWindow)
		{
			gtk_widget_hide(GTK_WIDGET(PrincipalWindow));
			gtk_widget_show(GTK_WIDGET(PrincipalWindow));
			/* if(argc>1) read_any_file(argv[1]);*/
			return 0;
		}
	}
	/* initialisation */
	initialise_global_orbitals_variables();
	read_opengl_file();

	/* Create new top level window. */
	PrincipalWindow = gtk_window_new( GTK_WINDOW_TOPLEVEL);
	gtk_window_set_title(GTK_WINDOW(PrincipalWindow), _("Gabedit : Orbitals/Density/Vibration"));
	 gtk_container_set_reallocate_redraws (GTK_CONTAINER (PrincipalWindow), TRUE);
  	gtk_window_set_default_size (GTK_WINDOW(PrincipalWindow),(gint)(ScreenWidth*0.5),(gint)(ScreenHeight*0.69));
	gtk_container_set_border_width(GTK_CONTAINER(PrincipalWindow), 1);
	init_child(PrincipalWindow,gtk_widget_destroy," Draw Dens. Orb. ");
	/* g_signal_connect(G_OBJECT(PrincipalWindow),"delete_event",(GCallback)close_window_orb,NULL);*/
	g_signal_connect(G_OBJECT(PrincipalWindow), "delete-event",G_CALLBACK(gtk_widget_hide_on_delete), NULL);
	gtk_window_set_transient_for(GTK_WINDOW(PrincipalWindow),GTK_WINDOW(Parent));

	vboxwin = create_vbox(PrincipalWindow);
	gtk_widget_realize(PrincipalWindow);
	hboxwin = gtk_hbox_new (FALSE, 0);
	gtk_box_pack_start (GTK_BOX(vboxwin), hboxwin, TRUE, TRUE, 2);
	gtk_widget_show (hboxwin);

	
	if (!NewGLArea(hboxwin)) return 0;

	create_status_bar_orb(vboxwin);
	create_status_progress_bar_orb(vboxwin);

	handleBoxColorMapGrid = create_color_map_show(vboxwin,NULL," Grid ");
	g_object_set_data(G_OBJECT(PrincipalWindow), "HandleboxColorMapGrid ", handleBoxColorMapGrid);

	handleBoxColorMapContours = create_color_map_show(vboxwin,NULL, "Contours ");
	g_object_set_data(G_OBJECT(PrincipalWindow), "HandleboxColorMapContours", handleBoxColorMapContours);

	handleBoxColorMapPlanesMapped = create_color_map_show(vboxwin,NULL," Planes colorcoded");
	g_object_set_data(G_OBJECT(PrincipalWindow), "HandleboxColorMapPlanesMapped", handleBoxColorMapPlanesMapped);

	set_icone(PrincipalWindow);
	gtk_widget_show(GTK_WIDGET(PrincipalWindow));
	color_map_hide(handleBoxColorMapGrid);
	color_map_hide(handleBoxColorMapContours);
	color_map_hide(handleBoxColorMapPlanesMapped);
	/* if(argc>1) read_any_file(argv[1]);*/

	first = FALSE;

	gtk_window_move(GTK_WINDOW(PrincipalWindow),0,0);
	InitializeAll();
	/*printCoefZlm();*/

	return 0;
}