Пример #1
0
int Booster::launchProcess()
{
    setEnvironmentBeforeLaunch();

    // Load the application and find out the address of main()
    loadMain();

    // make booster specific initializations unless booster is in boot mode
    if (!m_bootMode)
        preinit();

#ifdef WITH_COVERAGE
    __gcov_flush();
#endif

    // Close syslog
    closelog();

    // Jump to main()
    const int retVal = m_appData->entry()(m_appData->argc(), const_cast<char **>(m_appData->argv()));

#ifdef WITH_COVERAGE
    __gcov_flush();
#endif

    return retVal;
}
Пример #2
0
// Forwards Unix signals from invoker to the invoked process
static void sig_forwarder(int sig)
{
    if (g_invoked_pid >= 0)
    {
        if (kill(g_invoked_pid, sig) != 0)
        {
            if (sig == SIGTERM && errno == ESRCH)
            {
                report(report_info,
                       "Can't send signal SIGTERM to application [%i] "
                       "because application is already terminated. \n",
                       g_invoked_pid);
            }
            else
            {
                report(report_error,
                      "Can't send signal %i to application [%i]: %s \n",
                      sig, g_invoked_pid, strerror(errno));
            }
        }

        // Restore signal handlers
        sigs_restore();

        // Write signal number to the self-pipe
        char signal_id = (char) sig;
        write(g_signal_pipe[1], &signal_id, 1);

        // Send the signal to itself using the default handler
        raise(sig);
#ifdef WITH_COVERAGE
        __gcov_flush();
#endif
    }
}
Пример #3
0
int main(int argc, char *argv[])
{
    otInstance *instance;

#if OPENTHREAD_EXAMPLES_POSIX
    if (setjmp(gResetJump))
    {
        alarm(0);
#if OPENTHREAD_ENABLE_COVERAGE
        __gcov_flush();
#endif
        execvp(argv[0], argv);
    }
#endif

#if OPENTHREAD_ENABLE_MULTIPLE_INSTANCES
    size_t   otInstanceBufferLength = 0;
    uint8_t *otInstanceBuffer       = NULL;
#endif

pseudo_reset:

    otSysInit(argc, argv);

#if OPENTHREAD_ENABLE_MULTIPLE_INSTANCES
    // Call to query the buffer size
    (void)otInstanceInit(NULL, &otInstanceBufferLength);

    // Call to allocate the buffer
    otInstanceBuffer = (uint8_t *)malloc(otInstanceBufferLength);
    assert(otInstanceBuffer);

    // Initialize OpenThread with the buffer
    instance = otInstanceInit(otInstanceBuffer, &otInstanceBufferLength);
#else
    instance = otInstanceInitSingle();
#endif
    assert(instance);

    otCliUartInit(instance);

#if OPENTHREAD_ENABLE_DIAG
    otDiagInit(instance);
#endif

    while (!otSysPseudoResetWasRequested())
    {
        otTaskletsProcess(instance);
        otSysProcessDrivers(instance);
    }

    otInstanceFinalize(instance);
#if OPENTHREAD_ENABLE_MULTIPLE_INSTANCES
    free(otInstanceBuffer);
#endif

    goto pseudo_reset;

    return 0;
}
Пример #4
0
int gcov_flush(cp_grant_id_t grantid, int bufsize)
{
    /* Initialize global state. */
    pos=0;
    grant = grantid;
    gcov_buff_sz = bufsize;
    assert(!gcov_enable);
    assert(!gcov_opened);
    gcov_enable = 1;

    /* Trigger copying.
     * This function is not always available, but there is a do-nothing
     * version in libc so that executables can be linked even without
     * this code ever being activated.
     */
    __gcov_flush();

    /* Mark the end of the data, stop. */
    add_int(GCOVOP_END);
    assert(!gcov_opened);
    assert(gcov_enable);
    gcov_enable = 0;

    /* Return number of bytes used in buffer. */
    return pos;
}
Пример #5
0
static void _log(
	const gchar *log_domain,
	GLogLevelFlags log_level,
	const gchar *message,
	gpointer nothing G_GNUC_UNUSED)
{
	gint64 timenow = qev_time / G_USEC_PER_SEC;
	gchar date[1024];

	#ifdef QEV_LOG_DEBUG
		struct tm *now;
		now = localtime(&timenow);
		strftime(date, sizeof(date), "%H:%M:%S", now);
	#else
		snprintf(date, sizeof(date), "%" G_GINT64_FORMAT, timenow);
	#endif

	qev_lock_write_lock(&_lock);

	fprintf(_log_file, "%s - %s [%s] %s\n",
		log_domain, _get_level(log_level),
		date, message);

	qev_lock_write_unlock(&_lock);

	#ifdef QEV_TESTING
		__gcov_flush();
	#endif
}
Пример #6
0
static void coverage_exit(void *unused)
{
#if CONFIG_DEBUG_COVERAGE
	printk(BIOS_DEBUG, "Syncing coverage data.\n");
#endif
	__gcov_flush();
}
Пример #7
0
int
__gcov_execle (const char *path, char *arg, ...)
{
  va_list ap, aq;
  unsigned i, length;
  char **args;
  char **envp;

  __gcov_flush ();

  va_start (ap, arg);
  va_copy (aq, ap);

  length = 2;
  while (va_arg (ap, char *))
    length++;
  va_end (ap);

  args = (char **) alloca (length * sizeof (void *));
  args[0] = arg;
  for (i = 1; i < length; i++)
    args[i] = va_arg (aq, char *);
  envp = va_arg (aq, char **);
  va_end (aq);

  return execve (path, args, envp);
}
Пример #8
0
void
JNI_OnUnload (JavaVM, void *)
{
#ifndef __ANDROID__
  __gcov_flush ();
#endif
}
Пример #9
0
void
my_handler (int signum)
{
  printf ("received signal\n");
  printf ("%llu\n", i);
  __gcov_flush ();              /* dump coverage data on receiving SIGUSR1 */
}
Пример #10
0
/**
 * Exit calling process with exit(0) using a standard syslog message.
 * This function should be called from the main thread of a server process in
 * a "safe" context for calling exit(). Any service specific thing should be
 * cleaned up before calling this function. By calling exit(), registered exit
 * functions are called before the process is terminated.
 */
void daemon_exit(void)
{
	syslog(LOG_NOTICE, "exiting for shutdown");

	if (__gcov_flush) {
		__gcov_flush();
	}
	_Exit(0);
}
Пример #11
0
pid_t
__gcov_fork (void)
{
  pid_t pid;
  __gcov_flush ();
  pid = fork ();
  if (pid == 0)
    __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx);
  return pid;
}
Пример #12
0
    void quickExit(int code) {
#ifdef MONGO_GCOV
        __gcov_flush();
#endif

#if __has_feature(address_sanitizer)
        __lsan_do_leak_check();
#endif

        ::_exit(code);
    }
Пример #13
0
pid_t
__gcov_fork (void)
{
  pid_t pid;
  extern __gthread_mutex_t __gcov_flush_mx;
  __gcov_flush ();
  pid = fork ();
  if (pid == 0)
    __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx);
  return pid;
}
Пример #14
0
/**
 * \brief Send to master information that test suite finished its execution
 *
 *        GREENTEA_TEST_ENV_END and GREENTEA_TEST_ENV_EXIT messages
 *        are sent just before test suite execution finishes (noting
 *        else to do). You can place it just before you return from your
 *        main() function.
 *
 *        Code coverage: If MEBD_CFG_DEBUG_OPTIONS_COVERAGE is set in the
 *        project via build configuration function will output series
 *        of code coverage messages GREENTEA_TEST_ENV_LCOV_START with code
 *        coverage binary data. This data is captured by Greentea and can
 *        be used to generate LCOV reports.
 *
 * \param result Test suite result from DUT (0 - FAIl, !0 - SUCCESS)
 *
 */
static void greentea_notify_completion(const int result) {
    const char *val = result ? GREENTEA_TEST_ENV_SUCCESS : GREENTEA_TEST_ENV_FAILURE;
#ifdef MBED_CFG_DEBUG_OPTIONS_COVERAGE
    coverage_report = true;
    __gcov_flush();
    coverage_report = false;
#endif
    greentea_metrics_report();
    greentea_send_kv(GREENTEA_TEST_ENV_END, val);
    greentea_send_kv(GREENTEA_TEST_ENV_EXIT, 0);
}
Пример #15
0
void netstats(void) {
	pid_read(0);	// include all processes
	
	printf("Displaying network statistics only for sandboxes using a new network namespace.\n");
	
	// print processes
	while (1) {
		// set pid table
		int i;
		int itv = 5; 	// 5 second  interval
		pid_read(0);

		// start rx/tx measurements
		for (i = 0; i < max_pids; i++) {
			if (pids[i].level == 1)
				get_stats(i);
		}
		
		// wait 5 seconds
		firemon_sleep(itv);
		
		// grab screen size
		struct winsize sz;
		int row = 24;
		int col = 80;
		if (!ioctl(0, TIOCGWINSZ, &sz)) {
			col = sz.ws_col;
			row = sz.ws_row;
		}
		
		// start printing
		firemon_clrscr();
		char *header = get_header();
		if (strlen(header) > (size_t)col)
			header[col] = '\0';
		printf("%s\n", header);
		if (row > 0)
			row--;
		free(header);

		// start rx/tx measurements
		for (i = 0; i < max_pids; i++) {
			if (pids[i].level == 1) {
				get_stats(i);
				print_proc(i, itv, col);
			}
		}
#ifdef HAVE_GCOV
			__gcov_flush();
#endif
	}
}
Пример #16
0
int main() {
	int argc = 1;
	char* argv[] = {""};

	printf("--- Test Start ---\n"); // Required for automated testing
	testing::InitGoogleTest(&argc, argv);
	RUN_ALL_TESTS();

	__gcov_flush(); // Required for coverage testing
	printf("--- Test End ---\n"); // Required for automated testing

	return 0;
}
Пример #17
0
void
sighandler (int signo)
{
#ifdef SIMPLE_WAY
  exit (signo);
#else
  extern void __gcov_flush ();
  // flush out gcov stats data
  __gcov_flush ();
  // raise the signal again to crash process
  raise (signo);
#endif
}
Пример #18
0
/** @brief Kill the program in silence */
void xbt_abort(void)
{
#ifdef COVERAGE
  /* Call __gcov_flush on abort when compiling with coverage options. */
  extern void __gcov_flush(void);
  __gcov_flush();
#endif
#ifdef _WIN32
  /* It was said *in silence*.  We don't want to see the error message printed
   * by the Microsoft's implementation of abort(). */
  raise(SIGABRT);
  signal(SIGABRT, SIG_DFL);
  raise(SIGABRT);
#endif
  abort();
}
Пример #19
0
// return -1 if error, 0 if no error
void copy_file_as_user(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode) {
	pid_t child = fork();
	if (child < 0)
		errExit("fork");
	if (child == 0) {
		// drop privileges
		drop_privs(0);

		// copy, set permissions and ownership
		int rv = copy_file(srcname, destname, uid, gid, mode); // already a regular user
		if (rv)
			fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n");
#ifdef HAVE_GCOV
		__gcov_flush();
#endif
		_exit(0);
	}
	// wait for the child to finish
	waitpid(child, NULL, 0);
}
Пример #20
0
int tp_unittest_main(const char* path)
{
#ifdef RUN_ON_DEVICE
#ifdef APP_IOS
    char gcdaFolder[1024] = "";
    unsigned long uPathLen = 1024;
    GetDocumentPath(gcdaFolder, uPathLen);
    setenv("GCOV_PREFIX", gcdaFolder, 1);
    setenv("GCOV_PREFIX_STRIP", "1", 1);
#endif
#ifdef ANDROID
    setenv("GCOV_PREFIX", "/sdcard/wme_gcov/", 1);
    setenv("GCOV_PREFIX_STRIP", "6", 1);
#endif
#endif
    int argc = 1;
    const char *argv[] = {"tp_unittest_main"};
    if (NULL == path || strlen(path) <= 0)
        return 1;

    char xmlPath[1024] = "";
    sprintf(xmlPath, "xml:%s", path);

    printf("absolute path for XML:%s\n", xmlPath);
	::testing::GTEST_FLAG(output) = xmlPath;
	::testing::InitGoogleTest(&argc, (char **)argv);
    if(!g_sGTestFilter.empty()) {
        ::testing::FLAGS_gtest_filter = g_sGTestFilter.c_str();
    }
    int ret = RUN_ALL_TESTS();
    
#ifdef ENABLED_GCOV_FLAG
#if defined(MACOS) ||  defined(APP_IOS)
    __gcov_flush();
#endif
#ifdef ANDROID
    exit(0);
#endif
#endif
    return ret;
}
Пример #21
0
void fs_mkdir(const char *name) {
	EUID_ASSERT();

	// check directory name
	invalid_filename(name, 0); // no globbing
	char *expanded = expand_macros(name);
	if (strncmp(expanded, cfg.homedir, strlen(cfg.homedir)) != 0 &&
	    strncmp(expanded, "/tmp", 4) != 0) {
		fprintf(stderr, "Error: only directories in user home or /tmp are supported by mkdir\n");
		exit(1);
	}

	struct stat s;
	if (stat(expanded, &s) == 0) {
		// file exists, do nothing
		goto doexit;
	}

	// create directory
	pid_t child = fork();
	if (child < 0)
		errExit("fork");
	if (child == 0) {
		// drop privileges
		drop_privs(0);

		// create directory
		mkdir_recursive(expanded);
#ifdef HAVE_GCOV
		__gcov_flush();
#endif
		_exit(0);
	}
	// wait for the child to finish
	waitpid(child, NULL, 0);

doexit:
	free(expanded);
}
Пример #22
0
// return -1 if error, 0 if no error
void touch_file_as_user(const char *fname, uid_t uid, gid_t gid, mode_t mode) {
	pid_t child = fork();
	if (child < 0)
		errExit("fork");
	if (child == 0) {
		// drop privileges
		drop_privs(0);

		FILE *fp = fopen(fname, "w");
		if (fp) {
			fprintf(fp, "\n");
			SET_PERMS_STREAM(fp, uid, gid, mode);
			fclose(fp);
		}
#ifdef HAVE_GCOV
		__gcov_flush();
#endif
		_exit(0);
	}
	// wait for the child to finish
	waitpid(child, NULL, 0);
}
Пример #23
0
int
__gcov_execve (const char *path, char *const argv[], char *const envp[])
{
  __gcov_flush ();
  return execve (path, argv, envp);
}
Пример #24
0
int
__gcov_execvp (const char *path, char *const argv[])
{
  __gcov_flush ();
  return execvp (path, argv);
}
Пример #25
0
void appimage_set(const char *appimage) {
	assert(appimage);
	assert(devloop == NULL);	// don't call this twice!
	EUID_ASSERT();
	
#ifdef LOOP_CTL_GET_FREE	// test for older kernels; this definition is found in /usr/include/linux/loop.h
	// check appimage file
	invalid_filename(appimage);
	if (access(appimage, R_OK) == -1) {
		fprintf(stderr, "Error: cannot access AppImage file\n");
		exit(1);
	}

	// get appimage type and ELF size
	// a value of 0 means we are dealing with a type1 appimage
	long unsigned int size = appimage2_size(appimage);
	if (arg_debug)
		printf("AppImage ELF size %lu\n", size);

	// open appimage file
	/* coverity[toctou] */
	int ffd = open(appimage, O_RDONLY|O_CLOEXEC);
	if (ffd == -1) {
		fprintf(stderr, "Error: cannot open AppImage file\n");
		exit(1);
	}

	// find or allocate a free loop device to use
	EUID_ROOT();
	int cfd = open("/dev/loop-control", O_RDWR);
	if (cfd == -1) {
		fprintf(stderr, "Error: /dev/loop-control interface is not supported by your kernel\n");
		exit(1);
	}
	int devnr = ioctl(cfd, LOOP_CTL_GET_FREE);
	if (devnr == -1) {
		fprintf(stderr, "Error: cannot allocate a new loopback device\n");
		exit(1);
	}
	close(cfd);
	if (asprintf(&devloop, "/dev/loop%d", devnr) == -1)
		errExit("asprintf");
		
	int lfd = open(devloop, O_RDONLY);
	if (lfd == -1) {
		fprintf(stderr, "Error: cannot open %s\n", devloop);
		exit(1);
	}
	if (ioctl(lfd, LOOP_SET_FD, ffd) == -1) {
		fprintf(stderr, "Error: cannot configure the loopback device\n");
		exit(1);
	}
	
	if (size) {
		struct loop_info64 info;
		memset(&info, 0, sizeof(struct loop_info64));
		info.lo_offset = size;
		if (ioctl(lfd,  LOOP_SET_STATUS64, &info) == -1)
			errExit("configure appimage offset");
	}
	
	close(lfd);
	close(ffd);
	EUID_USER();

	// creates appimage mount point perms 0700
	if (asprintf(&mntdir, "%s/.appimage-%u",  RUN_FIREJAIL_APPIMAGE_DIR, getpid()) == -1)
		errExit("asprintf");
	EUID_ROOT();
	mkdir_attr(mntdir, 0700, getuid(), getgid());
	EUID_USER();
	
	// mount
	char *mode;
	if (asprintf(&mode, "mode=700,uid=%d,gid=%d", getuid(), getgid()) == -1)
		errExit("asprintf");
	EUID_ROOT();
	
	if (size == 0) {
		if (mount(devloop, mntdir, "iso9660",MS_MGC_VAL|MS_RDONLY,  mode) < 0)
			errExit("mounting appimage");
	}
	else {
		if (mount(devloop, mntdir, "squashfs",MS_MGC_VAL|MS_RDONLY,  mode) < 0)
			errExit("mounting appimage");
	}

	if (arg_debug)
		printf("appimage mounted on %s\n", mntdir);
	EUID_USER();

	// set environment
	if (setenv("APPIMAGE", appimage, 1) < 0)
		errExit("setenv");
	if (mntdir && setenv("APPDIR", mntdir, 1) < 0)
		errExit("setenv");

	// build new command line
	if (asprintf(&cfg.command_line, "%s/AppRun", mntdir) == -1)
		errExit("asprintf");
	
	free(mode);
#ifdef HAVE_GCOV
	__gcov_flush();
#endif
#else
	fprintf(stderr, "Error: /dev/loop-control interface is not supported by your kernel\n");
	exit(1);
#endif
}
Пример #26
0
void profile_read(const char *fname) {
	EUID_ASSERT();

	// exit program if maximum include level was reached
	if (include_level > MAX_INCLUDE_LEVEL) {
		fprintf(stderr, "Error: maximum profile include level was reached\n");
		exit(1);
	}

	// check file
	invalid_filename(fname);
	if (strlen(fname) == 0 || is_dir(fname)) {
		fprintf(stderr, "Error: invalid profile file\n");
		exit(1);
	}
	if (access(fname, R_OK)) {
		// if the file ends in ".local", do not exit
		const char *base = gnu_basename(fname);
		char *ptr = strstr(base, ".local");
		if (ptr && strlen(ptr) == 6)
			return;

		fprintf(stderr, "Error: cannot access profile file\n");
		exit(1);
	}

	// allow debuggers
	if (arg_allow_debuggers) {
		char *tmp = strrchr(fname, '/');
		if (tmp && *(tmp + 1) != '\0') {
			tmp++;
			if (strcmp(tmp, "disable-devel.inc") == 0)
				return;
		}
	}

	// open profile file:
	FILE *fp = fopen(fname, "r");
	if (fp == NULL) {
		fprintf(stderr, "Error: cannot open profile file %s\n", fname);
		exit(1);
	}

	int msg_printed = 0;

	// read the file line by line
	char buf[MAX_READ + 1];
	int lineno = 0;
	while (fgets(buf, MAX_READ, fp)) {
		++lineno;
		// remove empty space - ptr in allocated memory
		char *ptr = line_remove_spaces(buf);
		if (ptr == NULL)
			continue;

		// comments
		if (*ptr == '#' || *ptr == '\0') {
			free(ptr);
			continue;
		}

		// process quiet
		if (strcmp(ptr, "quiet") == 0) {
			arg_quiet = 1;
			free(ptr);
			continue;
		}
		if (!msg_printed) {
			if (!arg_quiet)
				fprintf(stderr, "Reading profile %s\n", fname);
			msg_printed = 1;
		}

		// process include
		if (strncmp(ptr, "include ", 8) == 0) {
			include_level++;

			// extract profile filename and new skip params
			char *newprofile = ptr + 8; // profile name

			// expand ${HOME}/ in front of the new profile file
			char *newprofile2 = expand_home(newprofile, cfg.homedir);

			// recursivity
			profile_read((newprofile2)? newprofile2:newprofile);
			include_level--;
			if (newprofile2)
				free(newprofile2);
			free(ptr);
			continue;
		}

		// verify syntax, exit in case of error
		if (profile_check_line(ptr, lineno, fname))
			profile_add(ptr);
// we cannot free ptr here, data is extracted from ptr and linked as a pointer in cfg structure
//		else {
//			free(ptr);
//		}
#ifdef HAVE_GCOV
		__gcov_flush();
#endif
	}
	fclose(fp);
}
Пример #27
0
static void gcov_handler(int signum)
{
  __gcov_flush();
  exit(1);
}
Пример #28
0
// disable shm in pulseaudio
void pulseaudio_init(void) {
	struct stat s;

	// do we have pulseaudio in the system?
	if (stat("/etc/pulse/client.conf", &s) == -1) {
		if (arg_debug)
			printf("/etc/pulse/client.conf not found\n");
		return;
	}

	// create the new user pulseaudio directory
	if (mkdir(RUN_PULSE_DIR, 0700) == -1)
		errExit("mkdir");
	// make it a mount point and add mount flags
	if (mount(RUN_PULSE_DIR, RUN_PULSE_DIR, NULL, MS_BIND, NULL) < 0 ||
	    mount(NULL, RUN_PULSE_DIR, NULL, MS_NOEXEC|MS_NODEV|MS_NOSUID|MS_BIND|MS_REMOUNT, NULL) < 0)
		errExit("mount RUN_PULSE_DIR");

	// create the new client.conf file
	char *pulsecfg = NULL;
	if (asprintf(&pulsecfg, "%s/client.conf", RUN_PULSE_DIR) == -1)
		errExit("asprintf");
	if (copy_file("/etc/pulse/client.conf", pulsecfg, -1, -1, 0644)) // root needed
		errExit("copy_file");
	FILE *fp = fopen(pulsecfg, "a+");
	if (!fp)
		errExit("fopen");
	fprintf(fp, "%s", "\nenable-shm = no\n");
	SET_PERMS_STREAM(fp, getuid(), getgid(), 0644);
	fclose(fp);
	// hand over the directory to the user
	if (set_perms(RUN_PULSE_DIR, getuid(), getgid(), 0700))
		errExit("set_perms");

	// create ~/.config/pulse directory if not present
	char *dir1;
	if (asprintf(&dir1, "%s/.config", cfg.homedir) == -1)
		errExit("asprintf");
	if (lstat(dir1, &s) == -1) {
		pid_t child = fork();
		if (child < 0)
			errExit("fork");
		if (child == 0) {
			// drop privileges
			drop_privs(0);

			int rv = mkdir(dir1, 0755);
			if (rv == 0) {
				if (set_perms(dir1, getuid(), getgid(), 0755))
					{;} // do nothing
			}
#ifdef HAVE_GCOV
			__gcov_flush();
#endif
			_exit(0);
		}
		// wait for the child to finish
		waitpid(child, NULL, 0);
		fs_logger2("create", dir1);
	}
	else {
		// we expect a user owned directory
		if (!S_ISDIR(s.st_mode) || s.st_uid != getuid()) {
			if (S_ISLNK(s.st_mode))
				fprintf(stderr, "Error: user .config is a symbolic link\n");
			else
				fprintf(stderr, "Error: user .config is not a directory owned by the current user\n");
			exit(1);
		}
	}
	free(dir1);

	if (asprintf(&dir1, "%s/.config/pulse", cfg.homedir) == -1)
		errExit("asprintf");
	if (lstat(dir1, &s) == -1) {
		pid_t child = fork();
		if (child < 0)
			errExit("fork");
		if (child == 0) {
			// drop privileges
			drop_privs(0);

			int rv = mkdir(dir1, 0700);
			if (rv == 0) {
				if (set_perms(dir1, getuid(), getgid(), 0700))
					{;} // do nothing
			}
#ifdef HAVE_GCOV
			__gcov_flush();
#endif
			_exit(0);
		}
		// wait for the child to finish
		waitpid(child, NULL, 0);
		fs_logger2("create", dir1);
	}
	else {
		// we expect a user owned directory
		if (!S_ISDIR(s.st_mode) || s.st_uid != getuid()) {
			if (S_ISLNK(s.st_mode))
				fprintf(stderr, "Error: user .config/pulse is a symbolic link\n");
			else
				fprintf(stderr, "Error: user .config/pulse is not a directory owned by the current user\n");
			exit(1);
		}
	}
	free(dir1);

	// if we have ~/.config/pulse mount the new directory, else set environment variable.
	char *homeusercfg;
	if (asprintf(&homeusercfg, "%s/.config/pulse", cfg.homedir) == -1)
		errExit("asprintf");
	if (stat(homeusercfg, &s) == 0) {
		// get a file descriptor for ~/.config/pulse, fails if there is any symlink
		int fd = safe_fd(homeusercfg, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
		if (fd == -1)
			errExit("safe_fd");
		// confirm the actual mount destination is owned by the user
		if (fstat(fd, &s) == -1 || s.st_uid != getuid())
			errExit("fstat");

		// mount via the link in /proc/self/fd
		char *proc;
		if (asprintf(&proc, "/proc/self/fd/%d", fd) == -1)
			errExit("asprintf");
		if (mount(RUN_PULSE_DIR, proc, "none", MS_BIND, NULL) < 0)
			errExit("mount pulseaudio");
		fs_logger2("tmpfs", homeusercfg);
		free(proc);
		close(fd);
		// check /proc/self/mountinfo to confirm the mount is ok
		MountData *mptr = get_last_mount();
		if (strcmp(mptr->dir, homeusercfg) != 0 || strcmp(mptr->fstype, "tmpfs") != 0)
			errLogExit("invalid pulseaudio mount");

		char *p;
		if (asprintf(&p, "%s/client.conf", homeusercfg) == -1)
			errExit("asprintf");
		fs_logger2("create", p);
		free(p);
	}

	else {
		// set environment
		if (setenv("PULSE_CLIENTCONFIG", pulsecfg, 1) < 0)
			errExit("setenv");
	}

	free(pulsecfg);
	free(homeusercfg);
}
Пример #29
0
static void
unix_signal_handler (int signum, siginfo_t * si, ucontext_t * uc)
{
  uword fatal = 0;

  /* These come in handy when looking at core files from optimized images */
  last_signum = signum;
  last_faulting_address = (uword) si->si_addr;

  syslog_msg = format (syslog_msg, "received signal %U, PC %U",
		       format_signal, signum, format_ucontext_pc, uc);

  if (signum == SIGSEGV)
    syslog_msg = format (syslog_msg, ", faulting address %p", si->si_addr);

  switch (signum)
    {
      /* these (caught) signals cause the application to exit */
    case SIGTERM:
      /*
       * Ignore SIGTERM if it's sent before we're ready.
       */
      if (unix_main.vlib_main && unix_main.vlib_main->main_loop_exit_set)
	{
	  syslog (LOG_ERR | LOG_DAEMON, "received SIGTERM, exiting...");
	  unix_main.vlib_main->main_loop_exit_now = 1;
	}
      else
	syslog (LOG_ERR | LOG_DAEMON, "IGNORE early SIGTERM...");
      break;
      /* fall through */
    case SIGQUIT:
    case SIGINT:
    case SIGILL:
    case SIGBUS:
    case SIGSEGV:
    case SIGHUP:
    case SIGFPE:
    case SIGABRT:
      fatal = 1;
      break;

      /* by default, print a message and continue */
    default:
      fatal = 0;
      break;
    }

#ifdef CLIB_GCOV
  /*
   * Test framework sends SIGTERM, so we need to flush the
   * code coverage stats here.
   */
  {
    void __gcov_flush (void);
    __gcov_flush ();
  }
#endif

  /* Null terminate. */
  vec_add1 (syslog_msg, 0);

  if (fatal)
    {
      syslog (LOG_ERR | LOG_DAEMON, "%s", syslog_msg);

      /* Address of callers: outer first, inner last. */
      uword callers[15];
      uword n_callers = clib_backtrace (callers, ARRAY_LEN (callers), 0);
      int i;
      for (i = 0; i < n_callers; i++)
	{
	  vec_reset_length (syslog_msg);

	  syslog_msg =
	    format (syslog_msg, "#%-2d 0x%016lx %U%c", i, callers[i],
		    format_clib_elf_symbol_with_address, callers[i], 0);

	  syslog (LOG_ERR | LOG_DAEMON, "%s", syslog_msg);
	}

      /* have to remove SIGABRT to avoid recusive - os_exit calling abort() */
      unsetup_signal_handlers (SIGABRT);

      os_exit (1);
    }
  else
    clib_warning ("%s", syslog_msg);

}
Пример #30
0
pid_t
__gcov_fork (void)
{
  __gcov_flush ();
  return fork ();
}