Example #1
0
static int handle_exec(struct task *task)
{
	debug(DEBUG_EVENT, "+++ process pid=%d exec", task->pid);

	if (unlikely(options.verbose))
		fprintf(stderr, "+++ process pid=%d exec\n", task->pid);

	if (!options.follow_exec)
		goto nofollow;

	if (process_exec(task) < 0) {
		fprintf(stderr, "couldn't reinitialize process %d after exec\n", task->pid);
		goto untrace;
	}

	return continue_task(task, 0);
nofollow:
	report_nofollow(task);
untrace:
	untrace_proc(task);
	return RET_DELETED;
}
Example #2
0
struct service_process *service_process_create(struct service *service)
{
	static unsigned int uid_counter = 0;
	struct service_process *process;
	unsigned int uid = ++uid_counter;
	const char *hostdomain;
	pid_t pid;
	bool process_forked;

	i_assert(service->status_fd[0] != -1);

	if (service->to_throttle != NULL) {
		/* throttling service, don't create new processes */
		return NULL;
	}
	if (service->list->destroying) {
		/* these services are being destroyed, no point in creating
		   new processes now */
		return NULL;
	}
	/* look this up before fork()ing so that it gets cached for all the
	   future lookups. */
	hostdomain = my_hostdomain();

	if (service->type == SERVICE_TYPE_ANVIL &&
	    service_anvil_global->pid != 0) {
		pid = service_anvil_global->pid;
		uid = service_anvil_global->uid;
		process_forked = FALSE;
	} else {
		pid = fork();
		process_forked = TRUE;
		service->list->fork_counter++;
	}

	if (pid < 0) {
		service_error(service, "fork() failed: %m");
		return NULL;
	}
	if (pid == 0) {
		/* child */
		service_process_setup_environment(service, uid, hostdomain);
		service_reopen_inet_listeners(service);
		service_dup_fds(service);
		drop_privileges(service);
		process_exec(service->executable, NULL);
	}
	i_assert(hash_table_lookup(service_pids, POINTER_CAST(pid)) == NULL);

	process = i_new(struct service_process, 1);
	process->service = service;
	process->refcount = 1;
	process->pid = pid;
	process->uid = uid;
	if (process_forked) {
		process->to_status =
			timeout_add(SERVICE_FIRST_STATUS_TIMEOUT_SECS * 1000,
				    service_process_status_timeout, process);
	}

	process->available_count = service->client_limit;
	service->process_count++;
	service->process_avail++;
	DLLIST_PREPEND(&service->processes, process);

	service_list_ref(service->list);
	hash_table_insert(service_pids, POINTER_CAST(process->pid), process);

	if (service->type == SERVICE_TYPE_ANVIL && process_forked)
		service_anvil_process_created(process);
	return process;
}
Example #3
0
/**
    Runs it all
*/
void scheduler( )
{
    u16 temp_proc;

    // While we have stuff on the queues or list
    while ( blocked_list 
    	    || high_head 
    	    || med_head 
    	    || low_head )
    {
        if ( blocked_list 
        	 && !high_head 
        	 && !med_head 
        	 && !low_head )
        {
            printf("******************\n");
            printf("CURRENT_TIME:\t%llu\n", get_time());
            printf("SET_TIME TO: mem[blocked_list]._proc._time:\t%llu\n", mem[blocked_list]._proc._time);
            printf("******************\n");

            set_time( mem[blocked_list]._proc._time );
            printf("before deq\n");
            
            printf("mem[blocked_list]._proc._arrid:\t%i\n", mem[blocked_list]._proc._arrid);
            printf("mem[mem[blocked_list]._proc._next]._proc._arrid:\t%i\n", mem[mem[blocked_list]._proc._next]._proc._arrid);
            printf("mem[mem[mem[blocked_list]._proc._next]._proc._next]._proc._arrid:\t%i\n", mem[mem[mem[blocked_list]._proc._next]._proc._next]._proc._arrid);

            printf("get_time():\t%llu\n", get_time());
            blocked_deq( );
            printf("after deq\n");
        }

        // High priority
        u8 count = 0;
        while ( high_head 
        	    && count < 4 )
        {
            printf("RUNNING HIGH\n");
            temp_proc = ready_deq( 1 );
            printf("mem[temp_proc]._proc._next:\t%llu\n", mem[temp_proc]._proc._next);
            
            if ( mem[temp_proc]._proc._next ) {
                int x = 1 / 0;
            }

            printf("starting execute process with: %i\n", temp_proc);
            process_exec( temp_proc, get_time( ) + 2500 );
            printf("starting blocked in high\n");
            blocked_deq( );
            printf("done with blocked in high\n");

            count++;
        }

        // Med priority
        count = 0;
        while ( med_head 
        	    && count < 2 )
        {
            printf("RUNNING MED\n");

            temp_proc = ready_deq( 2 );
            process_exec( temp_proc, get_time( ) + 2500 );
            blocked_deq( );

            count++;
        }

        // Low priority
        count = 0;
        while ( low_head 
        	    && count < 1 )
        {
            printf("RUNNING LOW\n");
            temp_proc = ready_deq( 3 );
            process_exec( temp_proc, get_time( ) + 2500 );
            blocked_deq( );

            count++;
        }

        // Try to make other processes with currents
        u16 result = 1;
        while ( result && PROC_POINT < MAX_PROCS )
        {
            printf("IN WHILE - get_time():\t%llu\n", get_time());
            printf("proc_init[PROC_POINT]._start_time:\t%llu\n", proc_init[PROC_POINT]._start_time);
            result = new_proc( proc_init[PROC_POINT]._start_time, proc_init[PROC_POINT]._run_time, proc_init[PROC_POINT]._code_size, proc_init[PROC_POINT]._data_size, proc_init[PROC_POINT]._priority );
            printf("result:\t%llu\n", result);
            //printf("get_time():\t%llu\n", get_time());
            //printf("proc_init[PROC_POINT]._start_time:\t%llu\n\n\n", proc_init[PROC_POINT]._start_time);

            // Proc is ready to start, we got something back, put it on the queue
            if ( result )
            {
                printf("----------------------------------------------\n");
                printf("WHILE - New Process Index #:\t%i\n", PROC_POINT);
                printf("proc_init[PROC_POINT]._start_time:\t%llu\n", proc_init[PROC_POINT]._start_time);
                printf("----------------------------------------------\n");
                PROC_POINT++;
                ready_enq( result );
            }
        }

        // Nothing on queues and list but we haven't ran all the processes
        if ( PROC_POINT < MAX_PROCS 
        	 && !blocked_list 
        	 && !high_head 
        	 && !med_head 
        	 && !low_head )
        {
            printf("----------------------------------------------\n");
            printf("CURRENT TIME BEFORE SET:\t%llu\n", get_time());

            set_time( proc_init[PROC_POINT]._start_time );
            temp_proc = new_proc( proc_init[PROC_POINT]._start_time, proc_init[PROC_POINT]._run_time, proc_init[PROC_POINT]._code_size, proc_init[PROC_POINT]._data_size, proc_init[PROC_POINT]._priority );
            
            printf("IF - New Process Index #:\t%i\n", PROC_POINT);
            printf("NEW PROCESSES START TIME:\t%llu\n", proc_init[PROC_POINT]._start_time);
            printf("CURRENT TIME AFTER SET:\t\t%llu\n", get_time());
            printf("----------------------------------------------\n\n\n");
            
            PROC_POINT++;

            printf("high_head:\t%i\n", high_head);
            printf("med_head:\t%i\n", med_head);
            printf("low_head:\t%i\n", low_head);
            printf("mem[high_head]._proc._next:\t%i\n", mem[high_head]._proc._next);
            printf("mem[med_head]._proc._next:\t%i\n", mem[med_head]._proc._next);
            printf("mem[low_head]._proc._next:\t%i\n", mem[low_head]._proc._next);

            ready_enq( temp_proc );

            printf("high_head:\t%i\n", high_head);
            printf("med_head:\t%i\n", med_head);
            printf("low_head:\t%i\n", low_head);
            printf("mem[high_head]._proc._next:\t%i\n", mem[high_head]._proc._next);
            printf("mem[med_head]._proc._next:\t%i\n", mem[med_head]._proc._next);
            printf("mem[low_head]._proc._next:\t%i\n", mem[low_head]._proc._next);
        }
    }
    printf("FINISHED EXECUTING\n");
}
Example #4
0
static void handle_exec(const char *args, GHashTable *optlist,
			WI_ITEM_REC *item)
{
	PROCESS_REC *rec;
        char *target, *level;
	int notice, signum, interactive, target_nick, target_channel;

	/* check that there's no unknown options. we allowed them
	   because signals can be used as options, but there should be
	   only one unknown option: the signal name/number. */
	signum = cmd_options_get_signal("exec", optlist);
	if (signum == -2)
                return;

	if (*args == '\0') {
		exec_show_list();
                return;
	}

	target = NULL;
	notice = FALSE;

	if (g_hash_table_lookup(optlist, "in") != NULL) {
		rec = process_find(g_hash_table_lookup(optlist, "in"), TRUE);
		if (rec != NULL) {
			net_sendbuffer_send(rec->out, args, strlen(args));
			net_sendbuffer_send(rec->out, "\n", 1);
		}
		return;
	}

	/* check if args is a process ID or name. if it's ID but not found,
	   complain about it and fail immediately */
	rec = process_find(args, *args == '%');
	if (*args == '%' && rec == NULL)
		return;

        /* common options */
        target_channel = target_nick = FALSE;
	if (g_hash_table_lookup(optlist, "out") != NULL) {
                /* redirect output to active channel/query */
		if (item == NULL)
			cmd_return_error(CMDERR_NOT_JOINED);
		target = (char *) window_item_get_target(item);
		target_channel = IS_CHANNEL(item);
		target_nick = IS_QUERY(item);
	} else if (g_hash_table_lookup(optlist, "msg") != NULL) {
                /* redirect output to /msg <nick> */
		target = g_hash_table_lookup(optlist, "msg");
	} else if (g_hash_table_lookup(optlist, "notice") != NULL) {
		target = g_hash_table_lookup(optlist, "notice");
                notice = TRUE;
	}

        /* options that require process ID/name as argument */
	if (rec == NULL &&
	    (signum != -1 || g_hash_table_lookup(optlist, "close") != NULL)) {
		printtext(NULL, NULL, MSGLEVEL_CLIENTERROR,
			  "Unknown process name: %s", args);
		return;
	}
	if (g_hash_table_lookup(optlist, "close") != NULL) {
		/* forcibly close the process */
                process_destroy(rec, -1);
                return;
	}

	if (signum != -1) {
		/* send a signal to process */
                kill(rec->pid, signum);
                return;
	}

        interactive = g_hash_table_lookup(optlist, "interactive") != NULL;
	if (*args == '%') {
		/* do something to already existing process */
		char *name;

		if (target != NULL) {
                        /* redirect output to target */
			g_free_and_null(rec->target);
			rec->target = g_strdup(target);
                        rec->notice = notice;
		}

                name = g_hash_table_lookup(optlist, "name");
		if (name != NULL) {
			/* change window name */
			g_free_not_null(rec->name);
			rec->name = *name == '\0' ? NULL : g_strdup(name);
		} else if (target == NULL &&
			   (rec->target_item == NULL || interactive)) {
			/* no parameters given,
			   redirect output to the active window */
			g_free_and_null(rec->target);
			rec->target_win = active_win;

			if (rec->target_item != NULL)
				exec_wi_destroy(rec->target_item);

			if (interactive) {
				rec->target_item =
					exec_wi_create(active_win, rec);
			}
		}
                return;
	}

        /* starting a new process */
	rec = g_new0(PROCESS_REC, 1);
	rec->pid = -1;
        rec->shell = g_hash_table_lookup(optlist, "nosh") == NULL;

	process_exec(rec, args);
	if (rec->pid == -1) {
                /* pipe() or fork() failed */
		g_free(rec);
		cmd_return_error(CMDERR_ERRNO);
	}

        rec->id = process_get_new_id();
	rec->target = g_strdup(target);
	rec->target_win = active_win;
	rec->target_channel = target_channel;
	rec->target_nick = target_nick;
        rec->args = g_strdup(args);
	rec->notice = notice;
        rec->silent = g_hash_table_lookup(optlist, "-") != NULL;
        rec->quiet = g_hash_table_lookup(optlist, "quiet") != NULL;
	rec->name = g_strdup(g_hash_table_lookup(optlist, "name"));

	level = g_hash_table_lookup(optlist, "level");
	rec->level = level == NULL ? MSGLEVEL_CLIENTCRAP : level2bits(level);

	rec->read_tag = g_input_add(rec->in, G_INPUT_READ,
				    (GInputFunction) sig_exec_input_reader,
				    rec);
	processes = g_slist_append(processes, rec);

	if (rec->target == NULL && interactive)
		rec->target_item = exec_wi_create(active_win, rec);

	signal_emit("exec new", 1, rec);
}