示例#1
0
文件: frag.c 项目: Fleurer/xfsprogs
static void
process_inode(
	xfs_agf_t		*agf,
	xfs_agino_t		agino,
	xfs_dinode_t		*dip)
{
	__uint64_t		actual;
	__uint64_t		ideal;
	xfs_ino_t		ino;
	int			skipa;
	int			skipd;

	ino = XFS_AGINO_TO_INO(mp, be32_to_cpu(agf->agf_seqno), agino);
	switch (be16_to_cpu(dip->di_mode) & S_IFMT) {
	case S_IFDIR:
		skipd = !dflag;
		break;
	case S_IFREG:
		if (!rflag && (be16_to_cpu(dip->di_flags) & XFS_DIFLAG_REALTIME))
			skipd = 1;
		else if (!Rflag &&
			 (ino == mp->m_sb.sb_rbmino ||
			  ino == mp->m_sb.sb_rsumino))
			skipd = 1;
		else if (!qflag &&
			 (ino == mp->m_sb.sb_uquotino ||
			  ino == mp->m_sb.sb_gquotino ||
			  ino == mp->m_sb.sb_pquotino))
			skipd = 1;
		else
			skipd = !fflag;
		break;
	case S_IFLNK:
		skipd = !lflag;
		break;
	default:
		skipd = 1;
		break;
	}
	actual = extcount_actual;
	ideal = extcount_ideal;
	if (!skipd)
		process_fork(dip, XFS_DATA_FORK);
	skipa = !aflag || !XFS_DFORK_Q(dip);
	if (!skipa)
		process_fork(dip, XFS_ATTR_FORK);
	if (vflag && (!skipd || !skipa))
		dbprintf(_("inode %lld actual %lld ideal %lld\n"),
			ino, extcount_actual - actual, extcount_ideal - ideal);
}
示例#2
0
文件: syscall.c 项目: bjornua/OSM
int syscall_fork(void (*func)(int), int arg)
{
    if (process_fork(func, arg) >= 0) {
        return 0;
    } else {
        return -1;
    }
}
示例#3
0
void main (int argc, char *argv[])
{
  int num_hello_world = 0;             // Used to store number of processes to create
  int i;                               // Loop index variable
  int child_pid;
  sem_t s_procs_completed;             // Semaphore used to wait until all spawned processes have completed
  char s_procs_completed_str[10];      // Used as command-line argument to pass page_mapped handle to new processes

  if (argc != 2) {
    Printf("Usage: %s <number of hello world processes to create>\n", argv[0]);
    Exit();
  }

  // Convert string from ascii command line argument to integer number
  num_hello_world = dstrtol(argv[1], NULL, 10); // the "10" means base 10
  Printf("makeprocs (%d): Creating %d hello_world processes\n", getpid(), num_hello_world);

  // Create semaphore to not exit this process until all other processes 
  // have signalled that they are complete.
  if ((s_procs_completed = sem_create(-(num_hello_world-1))) == SYNC_FAIL) {
    Printf("makeprocs (%d): Bad sem_create\n", getpid());
    Exit();
  }

  // Setup the command-line arguments for the new processes.  We're going to
  // pass the handles to the semaphore as strings
  // on the command line, so we must first convert them from ints to strings.
  ditoa(s_procs_completed, s_procs_completed_str);

  // Create Hello World processes
/*  Printf("-------------------------------------------------------------------------------------\n");
  Printf("makeprocs (%d): Creating %d hello world's in a row, but only one runs at a time\n", getpid(), num_hello_world);
  for(i=0; i<num_hello_world; i++) {
    Printf("makeprocs (%d): Creating hello world #%d\n", getpid(), i);
    process_create(HELLO_WORLD, s_procs_completed_str, NULL);
    if (sem_wait(s_procs_completed) != SYNC_SUCCESS) {
      Printf("Bad semaphore s_procs_completed (%d) in %s\n", s_procs_completed, argv[0]);
      Exit();
    }
  }
*/
//---------------------------------------this section for testing process_fork()--------------------------------------------------
   printf("the main program process ID is %d\n",(int)getpid());
   child_pid=process_fork();
   if(child_pid!=0){
      Printf ("this is the parent process with id %d\n",(int)getpid());
      Printf ("the child's process ID is %d\n",child_pid);
   }else {
      Printf ("this is the child process,with id %d\n",(int)getpid());
   }

  Printf("makeprocs (%d): exiting main process.\n", getpid());
  Printf("-------------------------------------------------------------------------------------\n");

}
示例#4
0
Profile *
tracker_create_profile (tracker_t *tracker)
{
    uint8_t *end = tracker->events + tracker->n_event_bytes;
    StackStash *resolved_stash;
    Profile *profile;
    state_t *state;
    uint8_t *event;

    state = state_new ();
    resolved_stash = stack_stash_new (g_free);

    event = tracker->events;
    while (event < end)
    {
	event_type_t type = GET_TYPE (*(uint32_t *)event);

	switch (type)
	{
	case NEW_PROCESS:
	    create_process (state, (new_process_t *)event);
	    event += sizeof (new_process_t);
	    break;

	case NEW_MAP:
	    create_map (state, (new_map_t *)event);
	    event += sizeof (new_map_t);
	    break;

	case FORK:
	    process_fork (state, (fork_t *)event);
	    event += sizeof (fork_t);
	    break;

	case EXIT:
	    process_exit (state, (exit_t *)event);
	    event += sizeof (exit_t);
	    break;

	case SAMPLE:
	    process_sample (state, resolved_stash, (sample_t *)event);
	    event += sizeof (sample_t);
	    break;
	}
    }
    
    profile = profile_new (resolved_stash);

    state_free (state);
    stack_stash_unref (resolved_stash);

    return profile;
}
示例#5
0
文件: alleyoop.c 项目: GNOME/alleyoop
void
alleyoop_run (Alleyoop *grind, GError **err)
{
	char logfd_arg[30];
	GPtrArray *args;
	int logfd[2];
	char **argv;
	int i;
	
	if (!grind->argv || !grind->argv[0])
		return;
	
	if (grind->pid != (pid_t) -1)
		return;
	
	if (pipe (logfd) == -1)
		return;
	
	args = alleyoop_prefs_create_argv ((AlleyoopPrefs *) grind->prefs, tool_names[grind->tool]);
	
	sprintf (logfd_arg, "--log-fd=%d", logfd[1]);
	g_ptr_array_add (args, logfd_arg);
	
	g_ptr_array_add (args, "--");
	for (i = 0; grind->argv[i] != NULL; i++)
		g_ptr_array_add (args, (char *) grind->argv[i]);
	g_ptr_array_add (args, NULL);
	
	argv = (char **) args->pdata;
	
	grind->pid = process_fork (argv[0], argv, TRUE, logfd[1], NULL, NULL, NULL, err);
	if (grind->pid == (pid_t) -1) {
		close (logfd[0]);
		close (logfd[1]);
		return;
	}
	
	g_ptr_array_free (args, TRUE);
	
	close (logfd[1]);
	
	vg_tool_view_connect ((VgToolView *) grind->view, logfd[0]);
	
	grind->gio = g_io_channel_unix_new (logfd[0]);
	grind->watch_id = g_io_add_watch (grind->gio, G_IO_IN | G_IO_HUP, io_ready_cb, grind);
	
	gtk_widget_set_sensitive (grind->toolbar_run, FALSE);
	gtk_widget_set_sensitive (grind->toolbar_kill, TRUE);
}
示例#6
0
static void system_sysc_fork(PSW* m) {
    DEBUG_PUTS(DEBUG_T_SYSC, "SYSCALL FORK()");
    
    Process* child = process_fork(process_current());
    
    if(child == NULL){
        ++m->PC;
        return;
    }

    m->AC = child->number;
    m->DR[m->RI.i] = child->number;
    ++m->PC;

    child->cpu.PC = m->PC;
    child->state = PROC_STATE_READY;
}
示例#7
0
int
process_daemonize(void)
{
	int pid;
#ifndef USE_DAEMON
	int i;

	switch(process_fork())
	{
		/* fork error */
		case -1:
			perror("fork()");
			exit(1);

		/* child process */
		case 0:
		/* obtain a new process group */
			if( (pid = setsid()) < 0)
			{
				perror("setsid()");
				exit(1);
			}

			/* close all descriptors */
			for (i=getdtablesize();i>=0;--i) close(i);		

			i = open("/dev/null",O_RDWR); /* open stdin */
			dup(i); /* stdout */
			dup(i); /* stderr */

			umask(027);
			chdir("/");

			break;
		/* parent process */
		default:
			exit(0);
	}
#else
	if( daemon(0, 0) < 0 )
		perror("daemon()");
	pid = getpid();
#endif
	return pid;
}
示例#8
0
static void
check_db(sqlite3 *db, int new_db, pid_t *scanner_pid)
{
    char cmd[PATH_MAX*2];
    int ret;
#ifdef MD_CHECK_MP
    struct media_dir_s *media_path = NULL;
    char **result;
    int i, rows = 0;

    if (!new_db)
    {
        /* Check if any new media dirs appeared */
        media_path = media_dirs;
        while (media_path)
        {
            ret = sql_get_int_field(db, "SELECT TIMESTAMP from DETAILS where PATH = %Q", media_path->path);
            if (ret != media_path->types)
            {
                ret = 1;
                goto rescan;
            }
            media_path = media_path->next;
        }
        /* Check if any media dirs disappeared */
        sql_get_table(db, "SELECT VALUE from SETTINGS where KEY = 'media_dir'", &result, &rows, NULL);
        for (i=1; i <= rows; i++)
        {
            media_path = media_dirs;
            while (media_path)
            {
                if (strcmp(result[i], media_path->path) == 0)
                    break;
                media_path = media_path->next;
            }
            if (!media_path)
            {
                ret = 2;
                sqlite3_free_table(result);
                goto rescan;
            }
        }
        sqlite3_free_table(result);
    }
#endif
    ret = db_upgrade(db);
    if ((ret != 0) || (GETFLAG(UPDATE_SCAN_MASK)))
    {
        if (ret != 0)
        {
#ifdef MD_CHECK_MP
rescan:
#endif
            if (ret < 0)
                DPRINTF(E_WARN, L_GENERAL, "Creating new database at %s/files.db\n", db_path);
#ifdef MD_CHECK_MP
            else if (ret == 1)
                DPRINTF(E_WARN, L_GENERAL, "New media_dir detected; rescanning...\n");
            else if (ret == 2)
                DPRINTF(E_WARN, L_GENERAL, "Removed media_dir detected; rescanning...\n");
#endif
            else
                DPRINTF(E_WARN, L_GENERAL, "Database version mismatch; need to recreate...\n");
            sqlite3_close(db);

            snprintf(cmd, sizeof(cmd), "rm -rf %s/files.db %s/art_cache", db_path, db_path);
            if (system(cmd) != 0)
                DPRINTF(E_FATAL, L_GENERAL, "Failed to clean old file cache!  Exiting...\n");

            open_db(&db);
            if (CreateDatabase() != 0)
                DPRINTF(E_FATAL, L_GENERAL, "ERROR: Failed to create sqlite database!  Exiting...\n");
        }
#if USE_FORK
        scanning = 1;
        sqlite3_close(db);
        *scanner_pid = process_fork();
        open_db(&db);
        if (*scanner_pid == 0) /* child (scanner) process */
        {
            start_scanner();
            sqlite3_close(db);
            log_close();
            freeoptions();
            exit(EXIT_SUCCESS);
        }
        else if (*scanner_pid < 0)
        {
            start_scanner();
        }
#else
        start_scanner();
#endif
    }
}
示例#9
0
文件: demo.c 项目: Distrotech/yodl
int main(int argc, char **argv)
{
    String *cmd = string_new(0);
    String *input = NULL;

    if (argc == 1)
    {
        fprintf(stderr,
            "Usage: %s [-s] prog [arg(s)]\n"
            "      -s: use system call, not std-input\n"
            "    prog: program or system call to execute\n"
            "  arg(s): optional arguments to prog\n"
            "Input to prog is read from stdin, unless -s was specified\n"
            "   (don't make this too long, it's stored in a String first)\n"
            "\n",
            argv[0]);

        exit(1);
    }

    bool syscall = !strcmp(argv[1], "-s");
    if (syscall)
    {
        argc--;
        argv++;
    }
    else
    {
        input = string_new(0);
        char buffer[100];

        fprintf(stderr, "Reading input from stdin...\n");

        while (fgets(buffer, 100, stdin))
            string_addstr(input, buffer);

        fprintf(stderr, "Input will be:\n"
                        "`%s'\n", string_str(input));
    }

    while (*++argv)
    {
        string_addstr(cmd, *argv);
        string_addchar(cmd, ' ');
    }


    fprintf(stderr, "Command will be:\n"
                        "`%s'\n", string_str(cmd));

    message_setseverity(MSG_ALL);
    message(MSG_NOTICE, "Creating Process");

    Process process;
    process_construct(&process, "process-demo", cmd,
                                                input);

    if (syscall)
        process_system(&process);
    else
        process_fork(&process);

    String const *out = process_output(&process);

    fprintf(stderr, "Output from process: '\n"
            "%s\n"
            "'\n", string_str(out));

    process_destroy(&process);

    return 0;
}
示例#10
0
// public API
APIE process_spawn(ObjectID executable_id, ObjectID arguments_id,
                   ObjectID environment_id, ObjectID working_directory_id,
                   uint32_t uid, uint32_t gid, ObjectID stdin_id,
                   ObjectID stdout_id, ObjectID stderr_id, Session *session,
                   uint16_t object_create_flags, bool release_on_death,
                   ProcessStateChangedFunction state_changed, void *opaque,
                   ObjectID *id, Process **object) {
	int phase = 0;
	APIE error_code;
	String *executable;
	List *arguments;
	Array arguments_array;
	int i;
	char **item;
	List *environment;
	Array environment_array;
	String *working_directory;
	File *stdin;
	File *stdout;
	File *stderr;
	pid_t pid;
	int status_pipe[2];
	int sc_open_max;
	FILE *log_file;
	Process *process;

	// acquire and lock executable string object
	error_code = string_get_acquired_and_locked(executable_id, &executable);

	if (error_code != API_E_SUCCESS) {
		goto cleanup;
	}

	phase = 1;

	if (*executable->buffer == '\0') {
		error_code = API_E_INVALID_PARAMETER;

		log_warn("Cannot spawn child process using empty executable name");

		goto cleanup;
	}

	// lock arguments list object
	error_code = list_get_acquired_and_locked(arguments_id, OBJECT_TYPE_STRING,
	                                          &arguments);

	if (error_code != API_E_SUCCESS) {
		goto cleanup;
	}

	phase = 2;

	// prepare arguments array for execvpe
	if (array_create(&arguments_array, 1 + arguments->items.count + 1, sizeof(char *), true) < 0) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not create arguments array for spawning child process (executable: %s): %s (%d)",
		          executable->buffer, get_errno_name(errno), errno);

		goto cleanup;
	}

	phase = 3;

	item = array_append(&arguments_array);

	if (item == NULL) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not append to arguments array for spawning child process (executable: %s): %s (%d)",
		          executable->buffer, get_errno_name(errno), errno);

		goto cleanup;
	}

	*item = executable->buffer;

	for (i = 0; i < arguments->items.count; ++i) {
		item = array_append(&arguments_array);

		if (item == NULL) {
			error_code = api_get_error_code_from_errno();

			log_error("Could not append to arguments array for spawning child process (executable: %s): %s (%d)",
			          executable->buffer, get_errno_name(errno), errno);

			goto cleanup;
		}

		*item = (*(String **)array_get(&arguments->items, i))->buffer;
	}

	item = array_append(&arguments_array);

	if (item == NULL) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not append to arguments array for spawning child process (executable: %s): %s (%d)",
		          executable->buffer, get_errno_name(errno), errno);

		goto cleanup;
	}

	*item = NULL;

	// lock environment list object
	error_code = list_get_acquired_and_locked(environment_id, OBJECT_TYPE_STRING,
	                                          &environment);

	if (error_code != API_E_SUCCESS) {
		goto cleanup;
	}

	phase = 4;

	// prepare environment array for execvpe
	if (array_create(&environment_array, environment->items.count + 1, sizeof(char *), true) < 0) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not create environment array for spawning child process (executable: %s): %s (%d)",
		          executable->buffer, get_errno_name(errno), errno);

		goto cleanup;
	}

	phase = 5;

	for (i = 0; i < environment->items.count; ++i) {
		item = array_append(&environment_array);

		if (item == NULL) {
			error_code = api_get_error_code_from_errno();

			log_error("Could not append to environment array for spawning child process (executable: %s): %s (%d)",
			          executable->buffer, get_errno_name(errno), errno);

			goto cleanup;
		}

		// FIXME: if item is not <name>=<value>, but just <name> then use the parent <value>

		*item = (*(String **)array_get(&environment->items, i))->buffer;
	}

	item = array_append(&environment_array);

	if (item == NULL) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not append to environment array for spawning child process (executable: %s): %s (%d)",
		          executable->buffer, get_errno_name(errno), errno);

		goto cleanup;
	}

	*item = NULL;

	// acquire and lock working directory string object
	error_code = string_get_acquired_and_locked(working_directory_id, &working_directory);

	if (error_code != API_E_SUCCESS) {
		goto cleanup;
	}

	phase = 6;

	if (*working_directory->buffer == '\0') {
		error_code = API_E_INVALID_PARAMETER;

		log_warn("Cannot spawn child process (executable: %s) using empty working directory name",
		         executable->buffer);

		goto cleanup;
	}

	if (*working_directory->buffer != '/') {
		error_code = API_E_INVALID_PARAMETER;

		log_warn("Cannot spawn child process (executable: %s) using working directory with relative name '%s'",
		         executable->buffer, working_directory->buffer);

		goto cleanup;
	}

	// acquire stdin file object
	error_code = file_get_acquired(stdin_id, &stdin);

	if (error_code != API_E_SUCCESS) {
		goto cleanup;
	}

	phase = 7;

	// acquire stdout file object
	error_code = file_get_acquired(stdout_id, &stdout);

	if (error_code != API_E_SUCCESS) {
		goto cleanup;
	}

	phase = 8;

	// acquire stderr file object
	error_code = file_get_acquired(stderr_id, &stderr);

	if (error_code != API_E_SUCCESS) {
		goto cleanup;
	}

	phase = 9;

	// create status pipe
	if (pipe(status_pipe) < 0) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not create status pipe for spawning child process (executable: %s): %s (%d)",
		          executable->buffer, get_errno_name(errno), errno);

		goto cleanup;
	}

	phase = 10;

	// fork
	log_debug("Forking to spawn child process (executable: %s)", executable->buffer);

	error_code = process_fork(&pid);

	if (error_code != API_E_SUCCESS) {
		goto cleanup;
	}

	if (pid == 0) { // child
		close(status_pipe[0]);

		// change user and groups
		error_code = process_set_identity(uid, gid);

		if (error_code != API_E_SUCCESS) {
			goto child_error;
		}

		// change directory
		if (chdir(working_directory->buffer) < 0) {
			error_code = api_get_error_code_from_errno();

			log_error("Could not change directory to '%s' for child process (executable: %s, pid: %u): %s (%d)",
			          working_directory->buffer, executable->buffer, getpid(), get_errno_name(errno), errno);

			goto child_error;
		}

		// get open FD limit
		sc_open_max = sysconf(_SC_OPEN_MAX);

		if (sc_open_max < 0) {
			error_code = api_get_error_code_from_errno();

			log_error("Could not get SC_OPEN_MAX value: %s (%d)",
			          get_errno_name(errno), errno);

			goto child_error;
		}

		// redirect stdin
		if (dup2(file_get_read_handle(stdin), STDIN_FILENO) != STDIN_FILENO) {
			error_code = api_get_error_code_from_errno();

			log_error("Could not redirect stdin for child process (executable: %s, pid: %u): %s (%d)",
			          executable->buffer, getpid(), get_errno_name(errno), errno);

			goto child_error;
		}

		// redirect stdout
		if (dup2(file_get_write_handle(stdout), STDOUT_FILENO) != STDOUT_FILENO) {
			error_code = api_get_error_code_from_errno();

			log_error("Could not redirect stdout for child process (executable: %s, pid: %u): %s (%d)",
			          executable->buffer, getpid(), get_errno_name(errno), errno);

			goto child_error;
		}

		// stderr is the default log output in non-daemon mode. if this is
		// the case then disable the log output before redirecting stderr to
		// avoid polluting stderr for the new process
		log_file = log_get_file();

		if (log_file != NULL && fileno(log_file) == STDERR_FILENO) {
			log_debug("Disable logging to stderr for child process (executable: %s, pid: %u)",
			          executable->buffer, getpid());

			log_set_file(NULL);
		}

		// redirect stderr
		if (dup2(file_get_write_handle(stderr), STDERR_FILENO) != STDERR_FILENO) {
			error_code = api_get_error_code_from_errno();

			log_error("Could not redirect stderr for child process (executable: %s, pid: %u): %s (%d)",
			          executable->buffer, getpid(), get_errno_name(errno), errno);

			goto child_error;
		}

		// notify parent
		if (robust_write(status_pipe[1], &error_code, sizeof(error_code)) < 0) {
			error_code = api_get_error_code_from_errno();

			log_error("Could not write to status pipe for child process (executable: %s, pid: %u): %s (%d)",
			          executable->buffer, getpid(), get_errno_name(errno), errno);

			goto child_error;
		}

		// disable log output. if stderr was not the current log output then
		// the log file is still open at this point. the next step is to close
		// all remaining file descriptors. just for good measure disable the
		// log output beforehand
		log_set_file(NULL);

		// close all file descriptors except the std* ones
		for (i = STDERR_FILENO + 1; i < sc_open_max; ++i) {
			close(i);
		}

		// execvpe only returns in case of an error
		execvpe(executable->buffer, (char **)arguments_array.bytes, (char **)environment_array.bytes);

		if (errno == ENOENT) {
			_exit(PROCESS_E_DOES_NOT_EXIST);
		} else {
			_exit(PROCESS_E_CANNOT_EXECUTE);
		}

	child_error:
		// notify parent in all cases
		if (robust_write(status_pipe[1], &error_code, sizeof(error_code)) < 0) {
			log_error("Could not write to status pipe for child process (executable: %s, pid: %u): %s (%d)",
			          executable->buffer, getpid(), get_errno_name(errno), errno);
		}

		close(status_pipe[1]);

		_exit(PROCESS_E_INTERNAL_ERROR);
	}

	phase = 11;

	// wait for child to start successfully
	if (robust_read(status_pipe[0], &error_code, sizeof(error_code)) < 0) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not read from status pipe for child process (executable: %s, pid: %u): %s (%d)",
		          executable->buffer, pid, get_errno_name(errno), errno);

		goto cleanup;
	}

	if (error_code != API_E_SUCCESS) {
		goto cleanup;
	}

	// create process object
	process = calloc(1, sizeof(Process));

	if (process == NULL) {
		error_code = API_E_NO_FREE_MEMORY;

		log_error("Could not allocate process object: %s (%d)",
		          get_errno_name(ENOMEM), ENOMEM);

		goto cleanup;
	}

	phase = 12;

	// setup process object
	process->executable = executable;
	process->arguments = arguments;
	process->environment = environment;
	process->working_directory = working_directory;
	process->uid = uid;
	process->gid = gid;
	process->pid = pid;
	process->stdin = stdin;
	process->stdout = stdout;
	process->stderr = stderr;
	process->release_on_death = release_on_death;
	process->state_changed = state_changed;
	process->opaque = opaque;
	process->state = PROCESS_STATE_RUNNING;
	process->timestamp = time(NULL);
	process->exit_code = 0; // invalid

	if (pipe_create(&process->state_change_pipe, 0) < 0) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not create state change pipe child process (executable: %s, pid: %u): %s (%d)",
		          executable->buffer, pid, get_errno_name(errno), errno);

		goto cleanup;
	}

	phase = 13;

	if (event_add_source(process->state_change_pipe.read_end, EVENT_SOURCE_TYPE_GENERIC,
	                     EVENT_READ, process_handle_state_change, process) < 0) {
		goto cleanup;
	}

	phase = 14;

	// create process object
	error_code = object_create(&process->base,
	                           OBJECT_TYPE_PROCESS,
	                           session,
	                           object_create_flags |
	                           OBJECT_CREATE_FLAG_INTERNAL,
	                           process_destroy,
	                           process_signature);

	if (error_code != API_E_SUCCESS) {
		goto cleanup;
	}

	phase = 15;

	if (id != NULL) {
		*id = process->base.id;
	}

	if (object != NULL) {
		*object = process;
	}

	// start thread to wait for child process state changes
	thread_create(&process->wait_thread, process_wait, process);

	log_debug("Spawned process object (id: %u, executable: %s, pid: %u)",
	          process->base.id, executable->buffer, process->pid);

	close(status_pipe[0]);
	close(status_pipe[1]);
	array_destroy(&arguments_array, NULL);
	array_destroy(&environment_array, NULL);

cleanup:
	switch (phase) { // no breaks, all cases fall through intentionally
	case 14:
		event_remove_source(process->state_change_pipe.read_end, EVENT_SOURCE_TYPE_GENERIC);

	case 13:
		pipe_destroy(&process->state_change_pipe);

	case 12:
		free(process);

	case 11:
		kill(pid, SIGKILL);

	case 10:
		close(status_pipe[0]);
		close(status_pipe[1]);

	case 9:
		file_release(stderr);

	case 8:
		file_release(stdout);

	case 7:
		file_release(stdin);

	case 6:
		string_unlock_and_release(working_directory);

	case 5:
		array_destroy(&environment_array, NULL);

	case 4:
		list_unlock_and_release(environment);

	case 3:
		array_destroy(&arguments_array, NULL);

	case 2:
		list_unlock_and_release(arguments);

	case 1:
		string_unlock_and_release(executable);

	default:
		break;
	}

	return phase == 15 ? API_E_SUCCESS : error_code;
}
示例#11
0
static void
process_event (Collector       *collector,
	       counter_t       *counter,
	       counter_event_t *event)
{
    char *name;
    
    switch (event->header.type)
    {
    case PERF_RECORD_MMAP: name = "mmap"; break;
    case PERF_RECORD_LOST: name = "lost"; break;
    case PERF_RECORD_COMM: name = "comm"; break;
    case PERF_RECORD_EXIT: name = "exit"; break;
    case PERF_RECORD_THROTTLE: name = "throttle"; break;
    case PERF_RECORD_UNTHROTTLE: name = "unthrottle"; break;
    case PERF_RECORD_FORK: name = "fork"; break;
    case PERF_RECORD_READ: name = "read"; break;
    case PERF_RECORD_SAMPLE: name = "samp"; break;
    default: name = "unknown"; break;
    }

    d_print ("cpu %d  ::  %s   :: ", counter->cpu, name);
    
    switch (event->header.type)
    {
    case PERF_RECORD_MMAP:
	process_mmap (collector, &event->mmap);
	break;
	
    case PERF_RECORD_LOST:
	g_print ("lost event\n");
	break;
	
    case PERF_RECORD_COMM:
	process_comm (collector, &event->comm);
	break;
	
    case PERF_RECORD_EXIT:
	process_exit (collector, &event->exit);
	break;
	
    case PERF_RECORD_THROTTLE:
	g_print ("throttle\n");
	break;
	
    case PERF_RECORD_UNTHROTTLE:
	g_print ("unthrottle\n");
	break;
	
    case PERF_RECORD_FORK:
	process_fork (collector, &event->fork);
	break;
	
    case PERF_RECORD_READ:
	break;
	
    case PERF_RECORD_SAMPLE:
	process_sample (collector, &event->sample);
	break;
	
    default:
	g_warning ("unknown event: %d (%d)\n",
		   event->header.type, event->header.size);
	break;
    }

    d_print ("\n");
}