Beispiel #1
0
static int
exec_file(pam_handle_t *pamh, char **argv, const char *logfile)
{
	pid_t pid, rc;
	int p[2];
	char buf[1024];
	long ttl;
	time_t start;
	int i, status, intr;
	fd_set rd;
	struct timeval tv;
	size_t total = 0;
	
	if (pipe(p)) {
		_pam_log(LOG_ERR, "pipe: %s", strerror(errno));
		return PAM_SYSTEM_ERR;
	}
		
	pid = fork();
	if (pid == -1) {
		close(p[0]);
		close(p[1]);
		_pam_log(LOG_ERR, "fork: %s", strerror(errno));
		return PAM_SYSTEM_ERR;
	}
	
	if (pid == 0) {		
		/* child */
		if (dup2(p[1], 1) == -1) {
			_pam_log(LOG_ERR, "dup2: %s", strerror(errno));
			_exit(127);
		}
		for (i = sysconf(_SC_OPEN_MAX); i >= 0; i--) {
			if (i != 1)
				close(i);
		}
		open("/dev/null", O_RDONLY);
		if (logfile) {
			if (open(logfile, O_CREAT|O_APPEND|O_WRONLY,
				 0644) == -1) {
				_pam_log(LOG_ERR, "open(%s): %s",
					 logfile, strerror(errno));
				_exit(127);
			}
		} else
			dup2(1, 2);
		
		execv(argv[0], argv);
		_exit(127);
	}

	/* master */
	close(p[1]);

	start = time(NULL);
	intr = 0;
	rc = 0;
	status = 0;
	for (i = 0; total < max_output_size;) {
		FD_ZERO(&rd);
		FD_SET(p[0], &rd);

		if (intr) {
			rc = waitpid(pid, &status, WNOHANG);
			if (rc == pid)
				break;
			if (rc == (pid_t)-1) {
				_pam_log(LOG_ERR, "waitpid: %s",
					 strerror(errno));
				break;
			}
			intr = 0;
		}
		ttl = timeout_option - (time(NULL) - start);
		if (ttl <= 0) {
			_pam_log(LOG_ERR, "timed out reading from %s",
				 argv[0]);
			break;
		}
		tv.tv_sec = ttl;
		tv.tv_usec = 0;
		rc = select(p[0] + 1, &rd, NULL, NULL, &tv);
		if (rc < 0) {
			if (errno == EINTR || errno == EAGAIN) {
				intr = 1;
				continue;
			}
			_pam_log(LOG_ERR, "select: %s", strerror(errno));
		}
		if (i == sizeof(buf) - 1) {
			char *p;
			buf[i] = 0;
			p = strrchr(buf, '\n');
			if (p)
				*p++ = 0;
			pam_info(pamh, "%s", buf);
			if (p && *p) {
				i = strlen(p);
				memmove(buf, p, i);
			}
		}
		if (FD_ISSET(p[0], &rd)) {
			char c;
			
			rc = read(p[0], &c, 1);
			if (rc == 1) {
				buf[i++] = c;
				total++;
			} else if (rc == 0
				   || errno == EINTR || errno == EAGAIN) {
				intr = 1;
				continue;
			} else {
				_pam_log(LOG_ERR, "read: %s", strerror(errno));
				break;
			}
		}
	}
	if (i) {
		buf[i] = 0;
		pam_info(pamh, "%s", buf);
	}
	close(p[0]);

	if (rc != pid) {
		_pam_log(LOG_NOTICE, "killing %s (pid %lu)",
			 argv[0], (unsigned long) pid);
		kill(pid, SIGKILL);
		
		while ((rc = waitpid(pid, &status, 0)) == -1 &&
		       errno == EINTR);
		if (rc == (pid_t)-1) {
			_pam_log(LOG_ERR, "waitpid: %s", strerror(errno));
			return PAM_SYSTEM_ERR;
		}
	} else if (WIFEXITED(status)) {
		status = WEXITSTATUS(status);
		if (status) {
			_pam_log(LOG_ERR, "%s exited with status %d",
				 argv[0], status);
			return PAM_SYSTEM_ERR;
		}
	} else if (WIFSIGNALED(status)) {
		status = WTERMSIG(status);
		_pam_log(LOG_ERR, "%s got signal %d", argv[0], status);
		return PAM_SYSTEM_ERR;
	} else if (status) {
		_pam_log(LOG_ERR, "%s failed: unknown status 0x%x",
			 argv[0], status);
		return PAM_SYSTEM_ERR;
	}
	return PAM_SUCCESS;
}
Beispiel #2
0
/* My goal is to launch a CCN transfert and verify success or failure and calculate the time taken */
int main (int argc, char **argv)
{
  struct timeval startTime;

  gettimeofday (&startTime, 0);
  pid_t fils = fork ();

  if ( -1 == fils )
    {
      fprintf (stderr,"fork failed !\n");
      exit (1);
    }
  if (fils)
    {
      // I am the father
      int status = 0;
      pid_t ret = waitpid (fils, &status, 0);
      struct timeval endTime;

      gettimeofday (&endTime, 0);
      if ( ret < 0 )
        {
          printf ("waitpid FAILURE\n");
          exit (3);
        }

      if (ret == fils)
        {
          if (WIFEXITED (status))
            {
              printf ("SUCCESS Exit Code %d ,Duration %ld\n", WEXITSTATUS(status), duration (&startTime, &endTime) );
              if ( WEXITSTATUS(status) )
                {
                  FILE *f  = fopen ("/var/log/FAILURE.TXT", "w+");
                  fprintf (f, "Failure PID %d, exit %d, duration %ld\n", fils, WEXITSTATUS(status), duration (&startTime, &endTime));
                  fclose (f);
                }
              else
                {
                  FILE *f  = fopen ("/var/log/SUCCESS.TXT", "w+");
                  fprintf (f, "%ld\n", duration (&startTime, &endTime));
                  fclose (f);
                }
              exit (WEXITSTATUS(status));
            }
          if (WIFSIGNALED (status))
            {
              printf ("SIGNALED : %d \n",  WTERMSIG(status));
              exit  (5);
            }
        }
      else
        {
          printf ("waitpid FAILURE\n");
          exit (4);
        }
      exit (ret);
    }
  else
    {
        int ret = execlp ("ccncatchunks2", "ccncatchunks2", "-d", "-a", "ccnx:/DATAFILE", NULL);
        printf ("exec return %d errno %d\n",ret , errno);
        exit (2);
    }
  exit (0);
}
RexxObjectPtr RexxEntry systemCommandHandler(RexxExitContext *context, RexxStringObject address, RexxStringObject command)
{
    const char *cmd = context->StringData(command);
    const char *envName = context->StringData(address);

    RexxObjectPtr rc = NULLOBJECT;

    /* check for redirection symbols, ignore them when enclosed in double quotes.
       escaped quotes are ignored. */
    bool noDirectInvoc = false;
    bool inQuotes = false;
    bool escape = false;
    size_t i;
    for (i = 0; i<strlen(cmd); i++)
    {
        if (escape)
        {
            escape = false;
        }
        else if (cmd[i] == '\\')
        {
            escape = true;
        }
        else if (cmd[i] == '"')
        {
            inQuotes = !inQuotes;
        }
        else
        {
            /* if we're in the unquoted part and the current character is one of */
            /* the redirection characters or the & for multiple commands then we */
            /* will no longer try to invoke the command directly                 */
            if (!inQuotes && (strchr("<>|&", cmd[i]) != NULL))
            {
                noDirectInvoc = true;
                break;
            }
        }
    }

    if (!noDirectInvoc)
    {
        /* execute 'cd' in the same process */
        size_t commandLen = strlen(cmd);

        if (strcmp(cmd, "cd") == 0)
        {
            if (sys_process_cd(context, cmd, rc))
            {
                return rc;
            }
        }
        else if (commandLen >= 3)
        {
            char tmp[16];
            strncpy(tmp, cmd, 3);
            tmp[3] = '\0';
            if (strcmp("cd ",tmp) == 0)
            {
                if (sys_process_cd(context, cmd, rc))
                {
                    return rc;
                }
            }
            strncpy(tmp, cmd, 4);
            tmp[4] = '\0';
            if (strcmp("set ",tmp) == 0)
            {
                if (sys_process_export(context, cmd, rc, SET_FLAG)) /*unset works fine for me*/
                {
                    return rc;
                }
            }
            strncpy(tmp, cmd, 6);
            tmp[6] = '\0';
            if (Utilities::strCaselessCompare("unset ", tmp) == 0)
            {
                if (sys_process_export(context, cmd, rc, UNSET_FLAG))
                {
                    return rc;
                }
            }
            strncpy(tmp, cmd, 7);
            tmp[7] = '\0';
            if (Utilities::strCaselessCompare("export ", tmp) == 0)
            {
                if (sys_process_export(context, cmd, rc, EXPORT_FLAG))
                {
                    return rc;
                }
            }
        }
    }


    /****************************************************************************/
    /* Invoke the system command handler to execute the command                 */
    /****************************************************************************/
    // if this is the null string, then use the default address environment
    // for the platform
    if (strlen(envName) == 0)
    {
        envName = SYSINITIALADDRESS;
    }

    int errCode = 0;

#ifdef LINUX

    if (Utilities::strCaselessCompare("bash", envName) == 0)
    {
        errCode = system( cmd );
        if ( errCode >= 256 )
        {
            errCode = errCode / 256;
        }
    }
    else
#endif
    {
        int pid = fork();
        int status;

        if (pid != 0)                         /* spawn a child process to run the  */
        {
            waitpid ( pid, &status, 0);          /* command and wait for it to finish */
            if (WIFEXITED(status))               /* If cmd process ended normal       */
            {
                                                 /* Give 'em the exit code            */
                errCode = WEXITSTATUS(status);
            }
            else                              /* Else process died ugly, so        */
            {
                errCode = -(WTERMSIG(status));
                if (errCode == 1)                    /* If process was stopped            */
                {
                    errCode = -1;                   /* Give 'em a -1.                    */
                }
            }
        }
        else
        {
        	/* run the command in the child      */
            if (Utilities::strCaselessCompare("sh", envName) == 0)
            {
				#ifdef ANDROID
            		execl("/system/bin/sh", "sh", "-c", cmd, NULL);
				#else
                    execl("/bin/sh", "sh", "-c", cmd, NULL);
				#endif
            }
            else if (Utilities::strCaselessCompare("ksh", envName) == 0)
            {
                execl("/bin/ksh", "ksh", "-c", cmd, NULL);
            }
            else if (Utilities::strCaselessCompare("bsh", envName) == 0)
            {
                execl("/bin/bsh", "bsh", "-c", cmd, NULL);
            }
            else if (Utilities::strCaselessCompare("csh", envName) == 0)
            {
                execl("/bin/csh", "csh", "-c", cmd, NULL);
            }
            else if (Utilities::strCaselessCompare("bash", envName) == 0)
            {
                execl("/bin/bash", "bash", "-c", cmd, NULL);
            }
            else if (Utilities::strCaselessCompare("cmd", envName) == 0)
            {
                char * args[MAX_COMMAND_ARGS+1];      /* Array for argument parsing */
                if (!scan_cmd(cmd, args))             /* Parse cmd into arguments  */
                {
                    exit(1);
                }
                execvp(args[0], args);           /* Invoke command directly   */
                exit(1);                         /* we couldn't run the       */
            }
            else
            {
                execl("/bin/sh", "sh", "-c", cmd, NULL);
            }
        }
    }
    // unknown command code?
    if (errCode == UNKNOWN_COMMAND)
    {
        // failure condition
        context->RaiseCondition("FAILURE", context->String(cmd), NULL, context->WholeNumberToObject(errCode));
    }
    else if (errCode != 0)
    {
        // non-zero is an error condition
        context->RaiseCondition("ERROR", context->String(cmd), NULL, context->WholeNumberToObject(errCode));
    }

    return context->False();      // zero return code
}
Beispiel #4
0
int runLINK()
{
#if _WIN32
    if (global.params.is64bit)
    {
        OutBuffer cmdbuf;

        cmdbuf.writestring("/NOLOGO ");

        for (size_t i = 0; i < global.params.objfiles->dim; i++)
        {
            if (i)
                cmdbuf.writeByte(' ');
            char *p = (*global.params.objfiles)[i];
            char *basename = FileName::removeExt(FileName::name(p));
            char *ext = FileName::ext(p);
            if (ext && !strchr(basename, '.'))
                // Write name sans extension (but not if a double extension)
                writeFilename(&cmdbuf, p, ext - p - 1);
            else
                writeFilename(&cmdbuf, p);
            mem.free(basename);
        }

        if (global.params.resfile)
        {
            cmdbuf.writeByte(' ');
            writeFilename(&cmdbuf, global.params.resfile);
        }

        cmdbuf.writeByte(' ');
        if (global.params.exefile)
        {   cmdbuf.writestring("/OUT:");
            writeFilename(&cmdbuf, global.params.exefile);
        }
        else
        {   /* Generate exe file name from first obj name.
             * No need to add it to cmdbuf because the linker will default to it.
             */
            char *n = (*global.params.objfiles)[0];
            n = FileName::name(n);
            FileName *fn = FileName::forceExt(n, "exe");
            global.params.exefile = fn->toChars();
        }

        // Make sure path to exe file exists
        {   char *p = FileName::path(global.params.exefile);
            FileName::ensurePathExists(p);
            mem.free(p);
        }

        cmdbuf.writeByte(' ');
        if (global.params.mapfile)
        {   cmdbuf.writestring("/MAP:");
            writeFilename(&cmdbuf, global.params.mapfile);
        }
        else if (global.params.map)
        {
            FileName *fn = FileName::forceExt(global.params.exefile, "map");

            char *path = FileName::path(global.params.exefile);
            char *p;
            if (path[0] == '\0')
                p = FileName::combine(global.params.objdir, fn->toChars());
            else
                p = fn->toChars();

            cmdbuf.writestring("/MAP:");
            writeFilename(&cmdbuf, p);
        }

        for (size_t i = 0; i < global.params.libfiles->dim; i++)
        {
            cmdbuf.writeByte(' ');
            cmdbuf.writestring("/DEFAULTLIB:");
            writeFilename(&cmdbuf, (*global.params.libfiles)[i]);
        }

        if (global.params.deffile)
        {
            cmdbuf.writeByte(' ');
            cmdbuf.writestring("/DEF:");
            writeFilename(&cmdbuf, global.params.deffile);
        }

        if (global.params.symdebug)
        {
            cmdbuf.writeByte(' ');
            cmdbuf.writestring("/DEBUG");
        }

        if (global.params.dll)
        {
            cmdbuf.writeByte(' ');
            cmdbuf.writestring("/DLL");
        }

        cmdbuf.writestring(" /MERGE:.minfobg=.minfodt /MERGE:.minfoen=.minfodt");
        cmdbuf.writestring(" /MERGE:._deh_bg=._deh_eh /MERGE:._deh_en=._deh_eh");

        for (size_t i = 0; i < global.params.linkswitches->dim; i++)
        {
            cmdbuf.writeByte(' ');
            cmdbuf.writestring((*global.params.linkswitches)[i]);
        }

        /* Append the path to the VC lib files, and then the SDK lib files
         */
        const char *vcinstalldir = getenv("VCINSTALLDIR");
        if (vcinstalldir)
        {   cmdbuf.writestring(" \"/LIBPATH:");
            cmdbuf.writestring(vcinstalldir);
            cmdbuf.writestring("lib\\amd64\"");
        }

        const char *windowssdkdir = getenv("WindowsSdkDir");
        if (windowssdkdir)
        {   cmdbuf.writestring(" \"/LIBPATH:");
            cmdbuf.writestring(windowssdkdir);
            cmdbuf.writestring("lib\\x64\"");
        }

        char *p = cmdbuf.toChars();

        FileName *lnkfilename = NULL;
        size_t plen = strlen(p);
        if (plen > 7000)
        {
            lnkfilename = FileName::forceExt(global.params.exefile, "lnk");
            File flnk(lnkfilename);
            flnk.setbuffer(p, plen);
            flnk.ref = 1;
            if (flnk.write())
                error(0, "error writing file %s", lnkfilename);
            if (lnkfilename->len() < plen)
                sprintf(p, "@%s", lnkfilename->toChars());
        }

        char *linkcmd = getenv("LINKCMD64");
        if (!linkcmd)
        {
            if (vcinstalldir)
            {
                OutBuffer linkcmdbuf;
                linkcmdbuf.writestring(vcinstalldir);
                linkcmdbuf.writestring("bin\\amd64\\link");
                linkcmd = linkcmdbuf.toChars();
                linkcmdbuf.extractData();
            }
            else
                linkcmd = "link";
        }
        int status = executecmd(linkcmd, p, 1);
        if (lnkfilename)
        {
            remove(lnkfilename->toChars());
            delete lnkfilename;
        }
        return status;
    }
    else
    {
        OutBuffer cmdbuf;

        global.params.libfiles->push("user32");
        global.params.libfiles->push("kernel32");

        for (size_t i = 0; i < global.params.objfiles->dim; i++)
        {
            if (i)
                cmdbuf.writeByte('+');
            char *p = (*global.params.objfiles)[i];
            char *basename = FileName::removeExt(FileName::name(p));
            char *ext = FileName::ext(p);
            if (ext && !strchr(basename, '.'))
                // Write name sans extension (but not if a double extension)
                writeFilename(&cmdbuf, p, ext - p - 1);
            else
                writeFilename(&cmdbuf, p);
            mem.free(basename);
        }
        cmdbuf.writeByte(',');
        if (global.params.exefile)
            writeFilename(&cmdbuf, global.params.exefile);
        else
        {   /* Generate exe file name from first obj name.
             * No need to add it to cmdbuf because the linker will default to it.
             */
            char *n = (*global.params.objfiles)[0];
            n = FileName::name(n);
            FileName *fn = FileName::forceExt(n, "exe");
            global.params.exefile = fn->toChars();
        }

        // Make sure path to exe file exists
        {   char *p = FileName::path(global.params.exefile);
            FileName::ensurePathExists(p);
            mem.free(p);
        }

        cmdbuf.writeByte(',');
        if (global.params.mapfile)
            writeFilename(&cmdbuf, global.params.mapfile);
        else if (global.params.map)
        {
            FileName *fn = FileName::forceExt(global.params.exefile, "map");

            char *path = FileName::path(global.params.exefile);
            char *p;
            if (path[0] == '\0')
                p = FileName::combine(global.params.objdir, fn->toChars());
            else
                p = fn->toChars();

            writeFilename(&cmdbuf, p);
        }
        else
            cmdbuf.writestring("nul");
        cmdbuf.writeByte(',');

        for (size_t i = 0; i < global.params.libfiles->dim; i++)
        {
            if (i)
                cmdbuf.writeByte('+');
            writeFilename(&cmdbuf, (*global.params.libfiles)[i]);
        }

        if (global.params.deffile)
        {
            cmdbuf.writeByte(',');
            writeFilename(&cmdbuf, global.params.deffile);
        }

        /* Eliminate unnecessary trailing commas    */
        while (1)
        {   size_t i = cmdbuf.offset;
            if (!i || cmdbuf.data[i - 1] != ',')
                break;
            cmdbuf.offset--;
        }

        if (global.params.resfile)
        {
            cmdbuf.writestring("/RC:");
            writeFilename(&cmdbuf, global.params.resfile);
        }

        if (global.params.map || global.params.mapfile)
            cmdbuf.writestring("/m");

#if 0
        if (debuginfo)
            cmdbuf.writestring("/li");
        if (codeview)
        {
            cmdbuf.writestring("/co");
            if (codeview3)
                cmdbuf.writestring(":3");
        }
#else
        if (global.params.symdebug)
            cmdbuf.writestring("/co");
#endif

        cmdbuf.writestring("/noi");
        for (size_t i = 0; i < global.params.linkswitches->dim; i++)
        {
            cmdbuf.writestring((*global.params.linkswitches)[i]);
        }
        cmdbuf.writeByte(';');

        char *p = cmdbuf.toChars();

        FileName *lnkfilename = NULL;
        size_t plen = strlen(p);
        if (plen > 7000)
        {
            lnkfilename = FileName::forceExt(global.params.exefile, "lnk");
            File flnk(lnkfilename);
            flnk.setbuffer(p, plen);
            flnk.ref = 1;
            if (flnk.write())
                error(0, "error writing file %s", lnkfilename);
            if (lnkfilename->len() < plen)
                sprintf(p, "@%s", lnkfilename->toChars());
        }

        char *linkcmd = getenv("LINKCMD");
        if (!linkcmd)
            linkcmd = "link";
        int status = executecmd(linkcmd, p, 1);
        if (lnkfilename)
        {
            remove(lnkfilename->toChars());
            delete lnkfilename;
        }
        return status;
    }
#elif linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun
    pid_t childpid;
    int status;

    // Build argv[]
    Strings argv;

    const char *cc = getenv("CC");
    if (!cc)
        cc = "gcc";
    argv.push((char *)cc);
    argv.insert(1, global.params.objfiles);

#if __APPLE__
    // If we are on Mac OS X and linking a dynamic library,
    // add the "-dynamiclib" flag
    if (global.params.dll)
        argv.push((char *) "-dynamiclib");
#elif linux || __FreeBSD__ || __OpenBSD__ || __sun
    if (global.params.dll)
        argv.push((char *) "-shared");
#endif

    // None of that a.out stuff. Use explicit exe file name, or
    // generate one from name of first source file.
    argv.push((char *)"-o");
    if (global.params.exefile)
    {
        if (global.params.dll)
            global.params.exefile = FileName::forceExt(global.params.exefile, global.dll_ext)->toChars();
        argv.push(global.params.exefile);
    }
    else
    {   // Generate exe file name from first obj name
        char *n = (*global.params.objfiles)[0];
        char *e;
        char *ex;

        n = FileName::name(n);
        e = FileName::ext(n);
        if (e)
        {
            e--;                        // back up over '.'
            ex = (char *)mem.malloc(e - n + 1);
            memcpy(ex, n, e - n);
            ex[e - n] = 0;
            // If generating dll then force dll extension
            if (global.params.dll)
                ex = FileName::forceExt(ex, global.dll_ext)->toChars();
        }
        else
            ex = (char *)"a.out";       // no extension, so give up
        argv.push(ex);
        global.params.exefile = ex;
    }

    // Make sure path to exe file exists
    {   char *p = FileName::path(global.params.exefile);
        FileName::ensurePathExists(p);
        mem.free(p);
    }

    if (global.params.symdebug)
        argv.push((char *)"-g");

    if (global.params.is64bit)
        argv.push((char *)"-m64");
    else
        argv.push((char *)"-m32");

    if (global.params.map || global.params.mapfile)
    {
        argv.push((char *)"-Xlinker");
#if __APPLE__
        argv.push((char *)"-map");
#else
        argv.push((char *)"-Map");
#endif
        if (!global.params.mapfile)
        {
            FileName *fn = FileName::forceExt(global.params.exefile, "map");

            char *path = FileName::path(global.params.exefile);
            char *p;
            if (path[0] == '\0')
                p = FileName::combine(global.params.objdir, fn->toChars());
            else
                p = fn->toChars();

            global.params.mapfile = p;
        }
        argv.push((char *)"-Xlinker");
        argv.push(global.params.mapfile);
    }

    if (0 && global.params.exefile)
    {
        /* This switch enables what is known as 'smart linking'
         * in the Windows world, where unreferenced sections
         * are removed from the executable. It eliminates unreferenced
         * functions, essentially making a 'library' out of a module.
         * Although it is documented to work with ld version 2.13,
         * in practice it does not, but just seems to be ignored.
         * Thomas Kuehne has verified that it works with ld 2.16.1.
         * BUG: disabled because it causes exception handling to fail
         * because EH sections are "unreferenced" and elided
         */
        argv.push((char *)"-Xlinker");
        argv.push((char *)"--gc-sections");
    }

    for (size_t i = 0; i < global.params.linkswitches->dim; i++)
    {   char *p = (*global.params.linkswitches)[i];
        if (!p || !p[0] || !(p[0] == '-' && (p[1] == 'l' || p[1] == 'L')))
            // Don't need -Xlinker if switch starts with -l or -L.
            // Eliding -Xlinker is significant for -L since it allows our paths
            // to take precedence over gcc defaults.
            argv.push((char *)"-Xlinker");
        argv.push(p);
    }

    /* Add each library, prefixing it with "-l".
     * The order of libraries passed is:
     *  1. any libraries passed with -L command line switch
     *  2. libraries specified on the command line
     *  3. libraries specified by pragma(lib), which were appended
     *     to global.params.libfiles.
     *  4. standard libraries.
     */
    for (size_t i = 0; i < global.params.libfiles->dim; i++)
    {   char *p = (*global.params.libfiles)[i];
        size_t plen = strlen(p);
        if (plen > 2 && p[plen - 2] == '.' && p[plen -1] == 'a')
            argv.push(p);
        else
        {
            char *s = (char *)mem.malloc(plen + 3);
            s[0] = '-';
            s[1] = 'l';
            memcpy(s + 2, p, plen + 1);
            argv.push(s);
        }
    }

    /* Standard libraries must go after user specified libraries
     * passed with -l.
     */
    const char *libname = (global.params.symdebug)
                                ? global.params.debuglibname
                                : global.params.defaultlibname;
    size_t slen = strlen(libname);
    if (slen)
    {
        char *buf = (char *)malloc(2 + slen + 1);
        strcpy(buf, "-l");
        strcpy(buf + 2, libname);
        argv.push(buf);             // turns into /usr/lib/libphobos2.a
    }

#ifdef __sun
    argv.push((char *)"-mt");
#endif

//    argv.push((void *)"-ldruntime");
    argv.push((char *)"-lpthread");
    argv.push((char *)"-lm");
#if linux && DMDV2
    // Changes in ld for Ubuntu 11.10 require this to appear after phobos2
    argv.push((char *)"-lrt");
#endif

    if (!global.params.quiet || global.params.verbose)
    {
        // Print it
        for (size_t i = 0; i < argv.dim; i++)
            printf("%s ", argv[i]);
        printf("\n");
        fflush(stdout);
    }

    argv.push(NULL);

    // set up pipes
    int fds[2];

    if (pipe(fds) == -1)
    {
        perror("Unable to create pipe to linker");
        return -1;
    }

    childpid = fork();
    if (childpid == 0)
    {
        // pipe linker stderr to fds[0]
        dup2(fds[1], STDERR_FILENO);
        close(fds[0]);

        execvp(argv[0], argv.tdata());
        perror(argv[0]);           // failed to execute
        return -1;
    }
    else if (childpid == -1)
    {
        perror("Unable to fork");
        return -1;
    }
    close(fds[1]);
    const int nme = findNoMainError(fds[0]);
    waitpid(childpid, &status, 0);

    if (WIFEXITED(status))
    {
        status = WEXITSTATUS(status);
        if (status)
        {
            if (nme == -1)
            {
                perror("Error with the linker pipe");
                return -1;
            }
            else
            {
                printf("--- errorlevel %d\n", status);
                if (nme == 1) error(0, "no main function specified");
            }
        }
    }
    else if (WIFSIGNALED(status))
    {
        printf("--- killed by signal %d\n", WTERMSIG(status));
        status = 1;
    }
    return status;
#else
    printf ("Linking is not yet supported for this version of DMD.\n");
    return -1;
#endif
}
Beispiel #5
0
/* Test each page.  */
static bool
TestPage(const char *pagelabel, uintptr_t pageaddr, int should_succeed)
{
    const char *oplabel;
    uintptr_t opaddr;

    bool failed = false;
    for (unsigned int test = 0; test < 3; test++) {
        switch (test) {
        // The execute test must be done before the write test, because the
        // write test will clobber memory at the target address.
        case 0:
            oplabel = "reading";
            opaddr = pageaddr + PAGESIZE/2 - 1;
            break;
        case 1:
            oplabel = "executing";
            opaddr = pageaddr + PAGESIZE/2;
            break;
        case 2:
            oplabel = "writing";
            opaddr = pageaddr + PAGESIZE/2 - 1;
            break;
        default:
            abort();
        }

#ifdef _WIN32
        BOOL badptr;

        switch (test) {
        case 0:
            badptr = IsBadReadPtr((const void*)opaddr, 1);
            break;
        case 1:
            badptr = IsBadExecPtr(opaddr);
            break;
        case 2:
            badptr = IsBadWritePtr((void*)opaddr, 1);
            break;
        default:
            abort();
        }

        if (badptr) {
            if (should_succeed) {
                printf("TEST-UNEXPECTED-FAIL | %s %s\n", oplabel, pagelabel);
                failed = true;
            } else {
                printf("TEST-PASS | %s %s\n", oplabel, pagelabel);
            }
        } else {
            // if control reaches this point the probe succeeded
            if (should_succeed) {
                printf("TEST-PASS | %s %s\n", oplabel, pagelabel);
            } else {
                printf("TEST-UNEXPECTED-FAIL | %s %s\n", oplabel, pagelabel);
                failed = true;
            }
        }
#elif defined(__OS2__)
        XCPT xcpt;
        volatile int code = setjmp(xcpt.jmpbuf);

        if (!code) {
            xcpt.regrec.prev_structure = 0;
            xcpt.regrec.ExceptionHandler = ExceptionHandler;
            DosSetExceptionHandler(&xcpt.regrec);
            unsigned char scratch;
            switch (test) {
            case 0:
                scratch = *(volatile unsigned char *)opaddr;
                break;
            case 1:
                ((void (*)())opaddr)();
                break;
            case 2:
                *(volatile unsigned char *)opaddr = 0;
                break;
            default:
                abort();
            }
        }

        if (code) {
            if (should_succeed) {
                printf("TEST-UNEXPECTED-FAIL | %s %s | exception code %x\n",
                       oplabel, pagelabel, code);
                failed = true;
            } else {
                printf("TEST-PASS | %s %s | exception code %x\n",
                       oplabel, pagelabel, code);
            }
        } else {
            if (should_succeed) {
                printf("TEST-PASS | %s %s\n", oplabel, pagelabel);
            } else {
                printf("TEST-UNEXPECTED-FAIL | %s %s\n", oplabel, pagelabel);
                failed = true;
            }
            DosUnsetExceptionHandler(&xcpt.regrec);
        }
#else
        pid_t pid = fork();
        if (pid == -1) {
            printf("ERROR | %s %s | fork=%s\n", oplabel, pagelabel,
                   LastErrMsg());
            exit(2);
        } else if (pid == 0) {
            volatile unsigned char scratch;
            switch (test) {
            case 0:
                scratch = *(volatile unsigned char *)opaddr;
                break;
            case 1:
                JumpTo(opaddr);
                break;
            case 2:
                *(volatile unsigned char *)opaddr = 0;
                break;
            default:
                abort();
            }
            (void)scratch;
            _exit(0);
        } else {
            int status;
            if (waitpid(pid, &status, 0) != pid) {
                printf("ERROR | %s %s | wait=%s\n", oplabel, pagelabel,
                       LastErrMsg());
                exit(2);
            }

            if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
                if (should_succeed) {
                    printf("TEST-PASS | %s %s\n", oplabel, pagelabel);
                } else {
                    printf("TEST-UNEXPECTED-FAIL | %s %s | unexpected successful exit\n",
                           oplabel, pagelabel);
                    failed = true;
                }
            } else if (WIFEXITED(status)) {
                printf("ERROR | %s %s | unexpected exit code %d\n",
                       oplabel, pagelabel, WEXITSTATUS(status));
                exit(2);
            } else if (WIFSIGNALED(status)) {
                if (should_succeed) {
                    printf("TEST-UNEXPECTED-FAIL | %s %s | unexpected signal %d\n",
                           oplabel, pagelabel, WTERMSIG(status));
                    failed = true;
                } else {
                    printf("TEST-PASS | %s %s | signal %d (as expected)\n",
                           oplabel, pagelabel, WTERMSIG(status));
                }
            } else {
                printf("ERROR | %s %s | unexpected exit status %d\n",
                       oplabel, pagelabel, status);
                exit(2);
            }
        }
#endif
    }
    return failed;
}
Beispiel #6
0
int
Mod_fw_replace(FW_handle_T handle, const char *set_name, List_T cidrs, short af)
{
    struct fw_handle *fwh = handle->fwh;
    int fd, nadded = 0, child = -1, status;
    char *cidr, *fd_path = NULL, *pfctl_path = PFCTL_PATH;
    char *table = (char *) set_name;
    static FILE *pf = NULL;
    struct List_entry *entry;
    struct sigaction act, oldact;
    char *argv[11] = { "pfctl", "-p", PFDEV_PATH, "-q", "-t", table,
                       "-T", "replace", "-f", "-", NULL };

    if(List_size(cidrs) == 0)
        return 0;

    pfctl_path = Config_get_str(handle->config, "pfctl_path",
                                "firewall", PFCTL_PATH);

    if(asprintf(&fd_path, "/dev/fd/%d", fwh->pfdev) == -1)
        return -1;
    argv[2] = fd_path;

    memset(&act, 0, sizeof(act));
    act.sa_handler = SIG_DFL;
    sigaction(SIGCHLD, &act, &oldact);

    if((pf = setup_cntl_pipe(pfctl_path, argv, &child)) == NULL) {
        free(fd_path);
        fd_path = NULL;
        goto err;
    }
    free(fd_path);
    fd_path = NULL;

    LIST_EACH(cidrs, entry) {
        if((cidr = List_entry_value(entry)) != NULL) {
            fprintf(pf, "%s\n", cidr);
            nadded++;
        }
    }
    fclose(pf);

    waitpid(child, &status, 0);
    if(WIFEXITED(status) && WEXITSTATUS(status) != 0) {
        i_warning("%s returned status %d", pfctl_path,
                  WEXITSTATUS(status));
        goto err;
    }
    else if(WIFSIGNALED(status)) {
        i_warning("%s died on signal %d", pfctl_path,
                  WTERMSIG(status));
        goto err;
    }

    signal(SIGCHLD, &oldact, NULL);

    return nadded;

err:
    return -1;
}
Beispiel #7
0
int main(int argc, char **argv)
{
	pid_t pid_fils, pid_ret;
	int statut_fils;

	pid=getpid(); ppid=getppid();
	printmsg("Creation depuis le shell");
	
	/* 1. Fonction en cas de terminaison du processus.
		 NB : elle sera heritee par le processus fils. */
	atexit(adieu);
	
	/* 2. Creation du processus fils */
	switch ( pid_fils = fork() )
		{
		case (pid_t)-1:
			/* Echec du fork */
			perror("main/fork");
			exit(EXIT_FAILURE);

		case (pid_t)0:
			/* DEBUT PROCESSUS FILS */
			strcpy(str_identp, "fils");
			strcpy(str_decale, "  ");
			pid=getpid(); ppid=getppid();
			printmsg("creation par processus pere");
				
			for(int i=1; i <= DURATION; i+=2)
				{
					printmsg("toujours vivant");
					sleep(2);
				}
			
			exit(EXIT_SUCCESS);
			/* FIN DU PROCESSUS FILS */
			
		default:
			/* Suite du processus pere */
			sprintf(str_buffer, "creation d'un processus fils de pid %d", pid_fils);
			printmsg(str_buffer);
		}
	
	/* 3. Attente non bloquante du processus fils */
	switch ( pid_ret = waitpid(pid_fils, &statut_fils, WNOHANG) )
		{
		case (pid_t)-1:
			/* Echec du waitpid */
			perror("main/waitpid WNOHANG");
			exit(EXIT_FAILURE);
			
		case (pid_t)0:
			/* Le processus fils attendu n'est pas termine */
			printmsg("attente fils non termine");

			/* 4. Attente bloquante du processus fils */
			switch( pid_ret =waitpid(pid_fils, &statut_fils, WUNTRACED) ) 
				{
				case (pid_t)-1:
					/* Echec du waitpid() */
					perror("main/waitpid WUNTRACED -1");
					exit(EXIT_FAILURE);

				case (pid_t)0:
					/* Ne devrait pas se produire */
					perror("main/waitpid WUNTRACED 0");
					exit(EXIT_FAILURE);

				default:
					/* Le processus fils attendu est termine */
					sprintf(str_buffer, "fin du fils de pid %d (pid demande = %d)", pid_ret, pid_fils);
					printmsg(str_buffer);
				}

			break;
			
		default:
			/* Le processus fils attendu est termine. */
			sprintf(str_buffer, "fin du fils de pid %d (pid demande = %d)", pid_ret, pid_fils);
			printmsg(str_buffer);
		}

	/* 5. Examen du code de retour du processus fils */
	if( WIFEXITED(statut_fils) != 0 )
		{
			sprintf(str_buffer, "code de retour du fils %d = %d",
							(int)pid_fils,
							WEXITSTATUS(statut_fils));
			printmsg(str_buffer);
		}
	
	if( WIFSIGNALED(statut_fils) != 0 )
		{
			sprintf(str_buffer, "fin du fils %d due au signal %d non intercepte",
							(int)pid_fils,
							WTERMSIG(statut_fils));
			printmsg(str_buffer);
		}
	
	if( WIFSTOPPED(statut_fils) != 0 )
		{
			sprintf(str_buffer, "processsus fils %d stoppe par signal %d",
							(int)pid_fils,
							WSTOPSIG(statut_fils));
			printmsg(str_buffer);
		}
	
	
	return EXIT_SUCCESS;
}
Beispiel #8
0
int main(int argc, char *argv[]) {
	int secs, stat;
	pid_t pid;
	unsigned int revs = 0;
	struct sigaction zig;

	if (argc < 3) {
		printf("Usage: %s time_in_sec command [args]\n", argv[0]);
		exit(1);
	}

	tty_fp = fdopen(3, "w+");
	if (tty_fp == NULL) {
		tty_fp = fopen("/dev/tty", "w+");
		if (tty_fp == NULL) {
			perror("stdout");
			exit(2);
		}
	}

	progname = rindex(argv[2], '/');
	if (progname == NULL) {
		progname = argv[2];
	} else {
		progname++;
	}

	/* Set up signals */
	memset(&zig, 0x00, sizeof(zig));
	zig.sa_handler = alarm_func;
	sigaction(SIGALRM, &zig, NULL);
	zig.sa_handler = int_func;
	sigaction(SIGINT, &zig, NULL);
	sigaction(SIGTERM, &zig, NULL);

	/* set up process groups so that we can kill the
	 * loop test and descendants easily */

	secs = atoi(argv[1]);
	alarm(secs);

	while (1) {
		pounder_fprintf(tty_fp, "%s: %s loop #%d.\n", progname, start_msg, revs++);
		pid = fork();
		if (pid == 0) {
			if (setpgrp() < 0) {
				perror("setpgid");
			}

			// run the program
			if (argc > 3) {
				stat = execvp(argv[2], &argv[2]);
			} else {
				stat = execvp(argv[2], &argv[2]);
			}

			perror(argv[2]);

			exit(-1);
		}

		/* save the pgrp of the spawned process */
		test_pgrp = pid;

		// wait for it to be done
		if (waitpid(pid, &stat, 0) != pid) {
			perror("waitpid");
			exit(1);
		}

		// interrogate it
		if (WIFSIGNALED(stat)) {
			pounder_fprintf(tty_fp, "%s: %s on signal %d.\n",
				progname, fail_msg, WTERMSIG(stat));
			res = 255;
		} else {
			res = WEXITSTATUS(stat);
			if (res == 0) {
				pounder_fprintf(tty_fp, "%s: %s.\n", progname, pass_msg);
			} else if (res < 0 || res == 255) {
				pounder_fprintf(tty_fp, "%s: %s with code %d.\n",
					progname, abort_msg, res);
				exit(-1);
				// FIXME: add test to blacklist
			} else {
				pounder_fprintf(tty_fp, "%s: %s with code %d.\n",
					progname, fail_msg, res);
			}
		}
	}
}
void
doit ()
{
  int err, i;
  int sockets[2];
  const char *srcdir;
  char *pub_key_path, *priv_key_path;
  pid_t child;

  gnutls_global_init ();

  srcdir = getenv ("srcdir") ? getenv ("srcdir") : ".";

  for (i = 0; i < 4; i++)
    {

      if (i <= 1)
        key_id = NULL;          /* try using the master key */
      else if (i == 2)
        key_id = "auto";        /* test auto */
      else if (i == 3)
        key_id = "f30fd423c143e7ba";

      if (debug)
        {
          gnutls_global_set_log_level (5);
          gnutls_global_set_log_function (log_message);
        }

      err = socketpair (PF_UNIX, SOCK_STREAM, 0, sockets);
      if (err != 0)
        fail ("socketpair %s\n", strerror (errno));

      pub_key_path = alloca (strlen (srcdir) + strlen (pub_key_file) + 2);
      strcpy (pub_key_path, srcdir);
      strcat (pub_key_path, "/");
      strcat (pub_key_path, pub_key_file);

      priv_key_path = alloca (strlen (srcdir) + strlen (priv_key_file) + 2);
      strcpy (priv_key_path, srcdir);
      strcat (priv_key_path, "/");
      strcat (priv_key_path, priv_key_file);

      child = fork ();
      if (child == -1)
        fail ("fork %s\n", strerror (errno));

      if (child == 0)
        {
          /* Child process (client).  */
          gnutls_session_t session;
          gnutls_certificate_credentials_t cred;
          ssize_t sent;

          if (debug)
            printf ("client process %i\n", getpid ());

          err = gnutls_init (&session, GNUTLS_CLIENT);
          if (err != 0)
            fail ("client session %d\n", err);

          if (i==0) /* we use the primary key which is RSA. Test the RSA ciphersuite */
            gnutls_priority_set_direct (session,
                                      "NONE:+VERS-TLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+RSA:+CTYPE-OPENPGP",
                                      NULL);
          else
            gnutls_priority_set_direct (session,
                                      "NONE:+VERS-TLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+DHE-DSS:+DHE-RSA:+CTYPE-OPENPGP",
                                      NULL);
          gnutls_transport_set_ptr (session,
                                    (gnutls_transport_ptr_t) (intptr_t)
                                    sockets[0]);

          err = gnutls_certificate_allocate_credentials (&cred);
          if (err != 0)
            fail ("client credentials %d\n", err);

          err =
            gnutls_certificate_set_openpgp_key_file2 (cred,
                                                      pub_key_path,
                                                      priv_key_path, key_id,
                                                      GNUTLS_OPENPGP_FMT_BASE64);
          if (err != 0)
            fail ("client openpgp keys %s\n", gnutls_strerror (err));

          err =
            gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, cred);
          if (err != 0)
            fail ("client credential_set %d\n", err);

          gnutls_dh_set_prime_bits (session, 1024);

          err = gnutls_handshake (session);
          if (err != 0)
            fail ("client handshake %s (%d) \n", gnutls_strerror (err), err);
          else if (debug)
            printf ("client handshake successful\n");

          sent = gnutls_record_send (session, message, sizeof (message));
          if (sent != sizeof (message))
            fail ("client sent %li vs. %li\n",
                  (long) sent, (long) sizeof (message));

          err = gnutls_bye (session, GNUTLS_SHUT_RDWR);
          if (err != 0)
            fail ("client bye %d\n", err);

          if (debug)
            printf ("client done\n");
          
          gnutls_deinit(session);
          gnutls_certificate_free_credentials (cred);
        }
      else
        {
          /* Parent process (server).  */
          gnutls_session_t session;
          gnutls_dh_params_t dh_params;
          gnutls_certificate_credentials_t cred;
          char greetings[sizeof (message) * 2];
          ssize_t received;
          pid_t done;
          int status;
          const gnutls_datum_t p3 = { (char *) pkcs3, strlen (pkcs3) };

          if (debug)
            printf ("server process %i (child %i)\n", getpid (), child);

          err = gnutls_init (&session, GNUTLS_SERVER);
          if (err != 0)
            fail ("server session %d\n", err);

          gnutls_priority_set_direct (session,
                                      "NONE:+VERS-TLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+DHE-DSS:+DHE-RSA:+RSA:+CTYPE-OPENPGP",
                                      NULL);
          gnutls_transport_set_ptr (session,
                                    (gnutls_transport_ptr_t) (intptr_t)
                                    sockets[1]);

          err = gnutls_certificate_allocate_credentials (&cred);
          if (err != 0)
            fail ("server credentials %d\n", err);

          err =
            gnutls_certificate_set_openpgp_key_file2 (cred,
                                                      pub_key_path,
                                                      priv_key_path, key_id,
                                                      GNUTLS_OPENPGP_FMT_BASE64);
          if (err != 0)
            fail ("server openpgp keys %s\n", gnutls_strerror (err));

          err = gnutls_dh_params_init (&dh_params);
          if (err)
            fail ("server DH params init %d\n", err);

          err =
            gnutls_dh_params_import_pkcs3 (dh_params, &p3,
                                           GNUTLS_X509_FMT_PEM);
          if (err)
            fail ("server DH params generate %d\n", err);

          gnutls_certificate_set_dh_params (cred, dh_params);

          err =
            gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, cred);
          if (err != 0)
            fail ("server credential_set %d\n", err);

          gnutls_certificate_server_set_request (session,
                                                 GNUTLS_CERT_REQUIRE);

          err = gnutls_handshake (session);
          if (err != 0)
            fail ("server handshake %s (%d) \n", gnutls_strerror (err), err);

          received =
            gnutls_record_recv (session, greetings, sizeof (greetings));
          if (received != sizeof (message)
              || memcmp (greetings, message, sizeof (message)))
            fail ("server received %li vs. %li\n", (long) received,
                  (long) sizeof (message));

          err = gnutls_bye (session, GNUTLS_SHUT_RDWR);
          if (err != 0)
            fail ("server bye %s (%d) \n", gnutls_strerror (err), err);

          if (debug)
            printf ("server done\n");

          gnutls_deinit(session);
          gnutls_certificate_free_credentials (cred);
          gnutls_dh_params_deinit (dh_params);

          done = wait (&status);
          if (done < 0)
            fail ("wait %s\n", strerror (errno));

          if (done != child)
            fail ("who's that?! %d\n", done);

          if (WIFEXITED (status))
            {
              if (WEXITSTATUS (status) != 0)
                fail ("child exited with status %d\n", WEXITSTATUS (status));
            }
          else if (WIFSIGNALED (status))
            fail ("child stopped by signal %d\n", WTERMSIG (status));
          else
            fail ("child failed: %d\n", status);
        }

    }
}
Beispiel #10
0
int
main(int argc, char **argv)
{
	int c;
        uid_t uid = -1;
        gid_t gid = -1;
        int pid;
        char **cmd;
        gid_t sgids[SUP_MAX];
        int sup_cnt = 0;
	int status;
	char *p;

	prog = basename(argv[0]);
	for (p = prog; *p; p++) {
		if (*p == '/') {
			prog = p + 1;
		}
	}


	while ((c = getopt(argc, argv, "u:g:s:")) != -1) {
		switch (c) {
		case 'u':
			uid = atoi(optarg);
			break;
		case 'g':
			gid = atoi(optarg);
			break;
		case 's':
			if (sup_cnt+1 > SUP_MAX) {
			    fprintf(stderr, "%s: too many sup groups\n", prog);
			    exit(1);
			}
			sgids[sup_cnt++] = atoi(optarg);
			break;
		case '?':
                        usage();
			exit(1);
		}
	}

        /* build up the cmd */
        if (optind == argc) {
            usage();
            exit(1);
        }
	else {
	    char **p;
	    p = cmd = (char **)malloc(sizeof(char *) * (argc - optind + 1));
	    for ( ; optind < argc; optind++, p++) {
	        *p = strdup(argv[optind]);
            }
	    *p = NULL;
	} 

        if (gid != -1) {
	    if (setegid(gid) == -1) {
		fprintf(stderr, "%s: setegid(%d) failed: %s\n",
			prog, (int)gid, strerror(errno));
		exit(1);
	    }	
        }

        if (sup_cnt > 0) {
	    if (setgroups(sup_cnt, sgids) == -1) {
		fprintf(stderr, "%s: setgroups() failed: %s\n",
			prog, strerror(errno));
		exit(1);
	    }	
	}

        if (uid != -1) {
	    if (seteuid(uid) == -1) {
		fprintf(stderr, "%s: seteuid(%d) failed: %s\n",
			prog, (int)uid, strerror(errno));
		exit(1);
	    }	
        }

	pid = fork();
	if (pid == -1) {
            fprintf(stderr, "%s: fork failed: %s\n",
	            prog, strerror(errno));
            exit(1);
        }
	if (pid == 0) {
            execv(cmd[0], cmd);
            fprintf(stderr, "%s: %s\n", cmd[0], strerror(errno));
            exit(errno);
	}

        wait(&status);
	if (WIFSIGNALED(status)) {
	    fprintf(stderr, "%s: command terminated with signal %d\n", 
                 prog, WTERMSIG(status));
	    exit(1);
	}
	else if (WIFEXITED(status)) {
	    exit(WEXITSTATUS(status));
        }
	else {
	    fprintf(stderr, "%s: command bizarre wait status 0x%x\n", 
               prog, status);
	    exit(1);
	}

	exit(0);
	/* NOTREACHED */
}
/* exit codes: 0 = ok, 1 = invocation error, 3 = internal error */
int main(int argc, char *argv[])
{
    int errNo;
    int chldPid;
    int chldStatus;
    int chldPipe[2];
    char **env = 0;
    struct sockaddr_un sau;

    if (argc < ArgEnv) {
        fprintf(stderr, "This is an internal helper of Qt Creator. Do not run it manually.\n");
        return 1;
    }
    sleepMsg = argv[ArgMsg];

    /* Connect to the master, i.e. Creator. */
    if ((qtcFd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
        perror("Cannot create creator comm socket");
        doExit(3);
    }
    memset(&sau, 0, sizeof(sau));
    sau.sun_family = AF_UNIX;
    strncpy(sau.sun_path, argv[ArgSocket], sizeof(sau.sun_path) - 1);
    if (connect(qtcFd, (struct sockaddr *)&sau, sizeof(sau))) {
        fprintf(stderr, "Cannot connect creator comm socket %s: %s\n", sau.sun_path, strerror(errno));
        doExit(1);
    }

    if (*argv[ArgDir] && chdir(argv[ArgDir])) {
        /* Only expected error: no such file or direcotry */
        sendMsg("err:chdir %d\n", errno);
        return 1;
    }

    if (*argv[ArgEnv]) {
        FILE *envFd;
        char *envdata, *edp;
        long size;
        int count;
        if (!(envFd = fopen(argv[ArgEnv], "r"))) {
            fprintf(stderr, "Cannot read creator env file %s: %s\n",
                    argv[ArgEnv], strerror(errno));
            doExit(1);
        }
        fseek(envFd, 0, SEEK_END);
        size = ftell(envFd);
        rewind(envFd);
        envdata = malloc(size);
        if (fread(envdata, 1, size, envFd) != (size_t)size) {
            perror("Failed to read env file");
            doExit(1);
        }
        fclose(envFd);
        for (count = 0, edp = envdata; edp < envdata + size; ++count)
            edp += strlen(edp) + 1;
        env = malloc((count + 1) * sizeof(char *));
        for (count = 0, edp = envdata; edp < envdata + size; ++count) {
            env[count] = edp;
            edp += strlen(edp) + 1;
        }
        env[count] = 0;
    }

    /* Create execution result notification pipe. */
    if (pipe(chldPipe)) {
        perror("Cannot create status pipe");
        doExit(3);
    }
    /* The debugged program is not supposed to inherit these handles. But we cannot
     * close the writing end before calling exec(). Just handle both ends the same way ... */
    fcntl(chldPipe[0], F_SETFD, FD_CLOEXEC);
    fcntl(chldPipe[1], F_SETFD, FD_CLOEXEC);
    switch ((chldPid = fork())) {
        case -1:
            perror("Cannot fork child process");
            doExit(3);
        case 0:
            close(qtcFd);

            /* Put the process into an own process group and make it the foregroud
             * group on this terminal, so it will receive ctrl-c events, etc.
             * This is the main reason for *all* this stub magic in the first place. */
            /* If one of these calls fails, the world is about to end anyway, so
             * don't bother checking the return values. */
            setpgid(0, 0);
            tcsetpgrp(0, getpid());

            /* Get a SIGTRAP after exec() has loaded the new program. */
#ifdef __linux__
            ptrace(PTRACE_TRACEME);
#else
            ptrace(PT_TRACE_ME, 0, 0, 0);
#endif

            if (env)
                environ = env;

            execvp(argv[ArgExe], argv + ArgExe);
            /* Only expected error: no such file or direcotry, i.e. executable not found */
            errNo = errno;
            write(chldPipe[1], &errNo, sizeof(errNo)); /* Only realistic error case is SIGPIPE */
            _exit(0);
        default:
            for (;;) {
                if (wait(&chldStatus) < 0) {
                    perror("Cannot obtain exit status of child process");
                    doExit(3);
                }
                if (WIFSTOPPED(chldStatus)) {
                    /* The child stopped. This can be only the result of ptrace(TRACE_ME). */
                    /* We won't need the notification pipe any more, as we know that
                     * the exec() succeeded. */
                    close(chldPipe[0]);
                    close(chldPipe[1]);
                    chldPipe[0] = -1;
                    /* If we are not debugging, just skip the "handover enabler".
                     * This is suboptimal, as it makes us ignore setuid/-gid bits. */
                    if (!strcmp(argv[ArgAction], "debug")) {
                        /* Stop the child after we detach from it, so we can hand it over to gdb.
                         * If the signal delivery is not queued, things will go awry. It works on
                         * Linux and MacOSX ... */
                        kill(chldPid, SIGSTOP);
                    }
#ifdef __linux__
                    ptrace(PTRACE_DETACH, chldPid, 0, 0);
#else
                    ptrace(PT_DETACH, chldPid, 0, 0);
#endif
                    sendMsg("pid %d\n", chldPid);
                } else if (WIFEXITED(chldStatus)) {
                    /* The child exited normally. */
                    if (chldPipe[0] >= 0) {
                        /* The child exited before being stopped by ptrace(). That can only
                         * mean that the exec() failed. */
                        switch (read(chldPipe[0], &errNo, sizeof(errNo))) {
                            default:
                                /* Read of unknown length. Should never happen ... */
                                errno = EPROTO;
                            case -1:
                                /* Read failed. Should never happen, either ... */
                                perror("Cannot read status from child process");
                                doExit(3);
                            case sizeof(errNo):
                                /* Child telling us the errno from exec(). */
                                sendMsg("err:exec %d\n", errNo);
                                return 3;
                        }
                    }
                    sendMsg("exit %d\n", WEXITSTATUS(chldStatus));
                    doExit(0);
                } else {
                    sendMsg("crash %d\n", WTERMSIG(chldStatus));
                    doExit(0);
                }
            }
            break;
    }
}
Beispiel #12
0
int jl_process_term_signal(int status) { return WTERMSIG(status); }
Beispiel #13
0
static void runner(int local, char *path, char **args)
{
	pid_t pid;

	if(show){
		int i;

		if(wrapper)
			fprintf(stderr, "WRAPPER='%s' ", wrapper);

		fprintf(stderr, "%s ", path);
		for(i = 0; args[i]; i++)
			fprintf(stderr, "%s ", args[i]);
		fputc('\n', stderr);
	}

	if(noop)
		return;


	/* if this were to be vfork, all the code in case-0 would need to be done in the parent */
	pid = fork();

	switch(pid){
		case -1:
			die("fork():");

		case 0:
		{
			int nargs = dynarray_count(args);
			int i_in = 0, i_out = 0;
			char **argv;

			/* -wrapper gdb,--args */
			if(wrapper){
				char *p;
				nargs++;
				for(p = wrapper; *p; p++)
					nargs += *p == ',';
			}

			/*
			 * path,
			 * { args }
			 * NULL-term
			 */
			argv = umalloc((2 + nargs) * sizeof *argv);

			/* wrapper */
			if(wrapper){
				char *p, *last;
				for(p = last = wrapper; *p; p++)
					if(*p == ','){
						*p = '\0';
						argv[i_out++] = last;
						last = p + 1;
					}

				if(last != p)
					argv[i_out++] = last;
			}

			argv[i_out++] = local ? actual_path("../", path) : path;

			while(args[i_in])
				argv[i_out++] = args[i_in++];

			argv[i_out++] = NULL;

#ifdef DEBUG
			fprintf(stderr, "%s:\n", *argv);
			for(int i = 0; argv[i]; i++)
				fprintf(stderr, "  [%d] = \"%s\",\n", i, argv[i]);
#endif

			if(wrapper)
				local = 0;

			(local ? execv : execvp)(argv[0], argv);
			die("execv(\"%s\"):", argv[0]);
		}

		default:
		{
			int status, i;
			if(wait(&status) == -1)
				die("wait()");

			if(WIFEXITED(status) && (i = WEXITSTATUS(status)) != 0){
				die("%s returned %d", path, i);
			}else if(WIFSIGNALED(status)){
				int sig = WTERMSIG(status);

				fprintf(stderr, "%s caught signal %d\n", path, sig);

				/* exit with propagating status */
				exit(128 + sig);
			}
		}
	}
}
Beispiel #14
0
/*-
 *-----------------------------------------------------------------------
 * CompatRunCommand --
 *	Execute the next command for a target. If the command returns an
 *	error, the node's made field is set to ERROR and creation stops.
 *
 * Input:
 *	cmdp		Command to execute
 *	gnp		Node from which the command came
 *
 * Results:
 *	0 if the command succeeded, 1 if an error occurred.
 *
 * Side Effects:
 *	The node's 'made' field may be set to ERROR.
 *
 *-----------------------------------------------------------------------
 */
int
CompatRunCommand(void *cmdp, void *gnp)
{
    char    	  *cmdStart;	/* Start of expanded command */
    char 	  *cp, *bp;
    Boolean 	  silent,   	/* Don't print command */
	    	  doIt;		/* Execute even if -n */
    volatile Boolean errCheck; 	/* Check errors */
    WAIT_T 	  reason;   	/* Reason for child's death */
    int	    	  status;   	/* Description of child's death */
    pid_t	  cpid;	    	/* Child actually found */
    pid_t	  retstat;    	/* Result of wait */
    LstNode 	  cmdNode;  	/* Node where current command is located */
    const char  ** volatile av;	/* Argument vector for thing to exec */
    char	** volatile mav;/* Copy of the argument vector for freeing */
    int	    	  argc;	    	/* Number of arguments in av or 0 if not
				 * dynamically allocated */
    Boolean 	  local;    	/* TRUE if command should be executed
				 * locally */
    Boolean 	  useShell;    	/* TRUE if command should be executed
				 * using a shell */
    char	  * volatile cmd = (char *)cmdp;
    GNode	  *gn = (GNode *)gnp;

    silent = gn->type & OP_SILENT;
    errCheck = !(gn->type & OP_IGNORE);
    doIt = FALSE;
    
    cmdNode = Lst_Member(gn->commands, cmd);
    cmdStart = Var_Subst(NULL, cmd, gn, FALSE);

    /*
     * brk_string will return an argv with a NULL in av[0], thus causing
     * execvp to choke and die horribly. Besides, how can we execute a null
     * command? In any case, we warn the user that the command expanded to
     * nothing (is this the right thing to do?).
     */

    if (*cmdStart == '\0') {
	free(cmdStart);
	return(0);
    }
    cmd = cmdStart;
    Lst_Replace(cmdNode, cmdStart);

    if ((gn->type & OP_SAVE_CMDS) && (gn != ENDNode)) {
	(void)Lst_AtEnd(ENDNode->commands, cmdStart);
	return(0);
    }
    if (strcmp(cmdStart, "...") == 0) {
	gn->type |= OP_SAVE_CMDS;
	return(0);
    }

    while ((*cmd == '@') || (*cmd == '-') || (*cmd == '+')) {
	switch (*cmd) {
	case '@':
	    silent = DEBUG(LOUD) ? FALSE : TRUE;
	    break;
	case '-':
	    errCheck = FALSE;
	    break;
	case '+':
	    doIt = TRUE;
	    if (!meta[0])		/* we came here from jobs */
		Compat_Init();
	    break;
	}
	cmd++;
    }

    while (isspace((unsigned char)*cmd))
	cmd++;

    /*
     * If we did not end up with a command, just skip it.
     */
    if (!*cmd)
	return (0);

#if !defined(MAKE_NATIVE)
    /*
     * In a non-native build, the host environment might be weird enough
     * that it's necessary to go through a shell to get the correct
     * behaviour.  Or perhaps the shell has been replaced with something
     * that does extra logging, and that should not be bypassed.
     */
    useShell = TRUE;
#else
    /*
     * Search for meta characters in the command. If there are no meta
     * characters, there's no need to execute a shell to execute the
     * command.
     */
    for (cp = cmd; !meta[(unsigned char)*cp]; cp++) {
	continue;
    }
    useShell = (*cp != '\0');
#endif

    /*
     * Print the command before echoing if we're not supposed to be quiet for
     * this one. We also print the command if -n given.
     */
    if (!silent || NoExecute(gn)) {
	printf("%s\n", cmd);
	fflush(stdout);
    }

    /*
     * If we're not supposed to execute any commands, this is as far as
     * we go...
     */
    if (!doIt && NoExecute(gn)) {
	return (0);
    }
    if (DEBUG(JOB))
	fprintf(debug_file, "Execute: '%s'\n", cmd);

again:
    if (useShell) {
	/*
	 * We need to pass the command off to the shell, typically
	 * because the command contains a "meta" character.
	 */
	static const char *shargv[5];
	int shargc;

	shargc = 0;
	shargv[shargc++] = shellPath;
	/*
	 * The following work for any of the builtin shell specs.
	 */
	if (errCheck && shellErrFlag) {
	    shargv[shargc++] = shellErrFlag;
	}
	if (DEBUG(SHELL))
		shargv[shargc++] = "-xc";
	else
		shargv[shargc++] = "-c";
	shargv[shargc++] = cmd;
	shargv[shargc++] = NULL;
	av = shargv;
	argc = 0;
	bp = NULL;
	mav = NULL;
    } else {
	/*
	 * No meta-characters, so no need to exec a shell. Break the command
	 * into words to form an argument vector we can execute.
	 */
	mav = brk_string(cmd, &argc, TRUE, &bp);
	if (mav == NULL) {
		useShell = 1;
		goto again;
	}
	av = (void *)mav;
    }

    local = TRUE;

#ifdef USE_META
    if (useMeta) {
	meta_compat_start();
    }
#endif
    
    /*
     * Fork and execute the single command. If the fork fails, we abort.
     */
    cpid = vFork();
    if (cpid < 0) {
	Fatal("Could not fork");
    }
    if (cpid == 0) {
	Var_ExportVars();
#ifdef USE_META
	if (useMeta) {
	    meta_compat_child();
	}
#endif
	if (local)
	    (void)execvp(av[0], (char *const *)UNCONST(av));
	else
	    (void)execv(av[0], (char *const *)UNCONST(av));
	execError("exec", av[0]);
	_exit(1);
    }
    if (mav)
	free(mav);
    if (bp)
	free(bp);
    Lst_Replace(cmdNode, NULL);

#ifdef USE_META
    if (useMeta) {
	meta_compat_parent();
    }
#endif

    /*
     * The child is off and running. Now all we can do is wait...
     */
    while (1) {

	while ((retstat = wait(&reason)) != cpid) {
	    if (retstat > 0)
		JobReapChild(retstat, reason, FALSE); /* not ours? */
	    if (retstat == -1 && errno != EINTR) {
		break;
	    }
	}

	if (retstat > -1) {
	    if (WIFSTOPPED(reason)) {
		status = WSTOPSIG(reason);		/* stopped */
	    } else if (WIFEXITED(reason)) {
		status = WEXITSTATUS(reason);		/* exited */
#if defined(USE_META) && defined(USE_FILEMON_ONCE)
		if (useMeta) {
		    meta_cmd_finish(NULL);
		}
#endif
		if (status != 0) {
		    if (DEBUG(ERROR)) {
		        fprintf(debug_file, "\n*** Failed target:  %s\n*** Failed command: ",
			    gn->name);
		        for (cp = cmd; *cp; ) {
    			    if (isspace((unsigned char)*cp)) {
				fprintf(debug_file, " ");
			        while (isspace((unsigned char)*cp))
				    cp++;
			    } else {
				fprintf(debug_file, "%c", *cp);
			        cp++;
			    }
		        }
			fprintf(debug_file, "\n");
		    }
		    printf("*** Error code %d", status);
		}
	    } else {
		status = WTERMSIG(reason);		/* signaled */
		printf("*** Signal %d", status);
	    }


	    if (!WIFEXITED(reason) || (status != 0)) {
		if (errCheck) {
#ifdef USE_META
		    if (useMeta) {
			meta_job_error(NULL, gn, 0, status);
		    }
#endif
		    gn->made = ERROR;
		    if (keepgoing) {
			/*
			 * Abort the current target, but let others
			 * continue.
			 */
			printf(" (continuing)\n");
		    }
		} else {
		    /*
		     * Continue executing commands for this target.
		     * If we return 0, this will happen...
		     */
		    printf(" (ignored)\n");
		    status = 0;
		}
	    }
	    break;
	} else {
	    Fatal("error in wait: %d: %s", retstat, strerror(errno));
	    /*NOTREACHED*/
	}
    }
    free(cmdStart);

    return (status);
}
Beispiel #15
0
static int
mountfs(const char *vfstype, const char *spec, const char *name, int flags,
        const char *options, const char *mntopts)
{
	/* List of directories containing mount_xxx subcommands. */
	static const char *edirs[] = {
		_PATH_SBIN,
		_PATH_USRSBIN,
		NULL
	};
	const char *argv[100], **edir;
	struct statfs sf;
	pid_t pid;
	int argc, i, status;
	char *optbuf, execname[MAXPATHLEN + 1], mntpath[MAXPATHLEN];

#if __GNUC__
	(void)&optbuf;
	(void)&name;
#endif

	/* resolve the mountpoint with realpath(3) */
	checkpath(name, mntpath);
	name = mntpath;

	if (mntopts == NULL)
		mntopts = "";
	if (options == NULL) {
		if (*mntopts == '\0') {
			options = "rw";
		} else {
			options = mntopts;
			mntopts = "";
		}
	}
	optbuf = catopt(xstrdup(mntopts), options);

	if (strcmp(name, "/") == 0)
		flags |= MNT_UPDATE;
	if (flags & MNT_FORCE)
		optbuf = catopt(optbuf, "force");
	if (flags & MNT_RDONLY)
		optbuf = catopt(optbuf, "ro");
	/*
	 * XXX
	 * The mount_mfs (newfs) command uses -o to select the
	 * optimization mode.  We don't pass the default "-o rw"
	 * for that reason.
	 */
	if (flags & MNT_UPDATE)
		optbuf = catopt(optbuf, "update");

	argc = 0;
	argv[argc++] = vfstype;
	mangle(optbuf, &argc, argv);
	argv[argc++] = spec;
	argv[argc++] = name;
	argv[argc] = NULL;

	if (debug) {
		printf("exec: mount_%s", vfstype);
		for (i = 1; i < argc; i++)
			printf(" %s", argv[i]);
		printf("\n");
		return (0);
	}

	switch (pid = fork()) {
	case -1:				/* Error. */
		warn("fork");
		free(optbuf);
		return (1);
	case 0:					/* Child. */
		if (strcmp(vfstype, "ufs") == 0)
			exit(mount_ufs(argc, argv));

		/* Go find an executable. */
		for (edir = edirs; *edir; edir++) {
			snprintf(execname,
			    sizeof(execname), "%s/mount_%s", *edir, vfstype);
			execv(execname, __DECONST(char * const *, argv));
		}
		if (errno == ENOENT) {
			int len = 0;
			char *cp;
			for (edir = edirs; *edir; edir++)
				len += strlen(*edir) + 2;	/* ", " */
			if ((cp = malloc(len)) == NULL)
				errx(1, "malloc failed");
			cp[0] = '\0';
			for (edir = edirs; *edir; edir++) {
				strcat(cp, *edir);
				if (edir[1] != NULL)
					strcat(cp, ", ");
			}
			warn("exec mount_%s not found in %s", vfstype, cp);
		}
		exit(1);
		/* NOTREACHED */
	default:				/* Parent. */
		free(optbuf);

		if (waitpid(pid, &status, 0) < 0) {
			warn("waitpid");
			return (1);
		}

		if (WIFEXITED(status)) {
			if (WEXITSTATUS(status) != 0)
				return (WEXITSTATUS(status));
		} else if (WIFSIGNALED(status)) {
			warnx("%s: %s", name, sys_siglist[WTERMSIG(status)]);
			return (1);
		}

		if (verbose) {
			if (statfs(name, &sf) < 0) {
				warn("statfs %s", name);
				return (1);
			}
			if (fstab_style)
				putfsent(&sf);
			else
				prmount(&sf);
		}
		break;
	}

	return (0);
}
Beispiel #16
0
/*
 * sigchld_handler - The kernel sends a SIGCHLD to the shell whenever
 *     a child job terminates (becomes a zombie), or stops because it
 *     received a SIGSTOP or SIGTSTP signal. The handler reaps all
 *     available zombie children, but doesn't wait for any other
 *     currently running children to terminate.
 */
void sigchld_handler(int sig)
{
    /* reaps all zombie and doesn't block */
    pid_t reap_pid;
    int state = 0;  /* used to determine what causes the SIGCHLD */
    /* waitpid() return 0 immediately when no childs have terminated */
    while (0 < (reap_pid = waitpid(-1, &state, WNOHANG))) {
        /* DBG(("reaped child %d", (int)reap_pid)); */
        /*TODO Is it safe to call getjobpid(), deletejob(), clearjob() in the signal handler?  */
        if (WIFSIGNALED(state)) {
            struct job_t *termjob = getjobpid(jobs, reap_pid);
            fprintf(stdout, "hello Job [%d] (%d) terminated by signal %d\n", termjob->jid, termjob->pid, WTERMSIG(state));
        }
        deletejob(jobs, reap_pid);
        clearjob(getjobpid(jobs, reap_pid));
    }

    if (-1 == reap_pid && errno != ECHILD)
        unix_error("waitpid()");

    /* if a job be suspended, we need to change its state here */
    pid_t stp_pid;
    /* waitpid return 0 if there is no terminated process and stopped process */
    while (0 < (stp_pid = waitpid(-1, &state, WNOHANG | WUNTRACED))) {
        struct job_t *stpjob = getjobpid(jobs, stp_pid);
        stpjob->state = ST;
        if (WIFSTOPPED(state)) {
            fprintf(stdout, "world Job [%d] (%d) stopped by signal %d\n", stpjob->jid, stpjob->pid, WSTOPSIG(state));
        }
    }

    if (-1 == stp_pid && errno != ECHILD)
        unix_error("waitpid()");
}
Beispiel #17
0
static bool fuzz_prepareFileExternally(honggfuzz_t * hfuzz, fuzzer_t * fuzzer, int rnd_index)
{
    int dstfd = open(fuzzer->fileName, O_CREAT | O_EXCL | O_RDWR, 0644);
    if (dstfd == -1) {
        PLOG_E("Couldn't create a temporary file '%s'", fuzzer->fileName);
        return false;
    }

    LOG_D("Created '%s' as an input file", fuzzer->fileName);

    if (hfuzz->inputFile) {
        size_t fileSz =
            files_readFileToBufMax(hfuzz->files[rnd_index], fuzzer->dynamicFile, hfuzz->maxFileSz);
        if (fileSz == 0UL) {
            LOG_E("Couldn't read '%s'", hfuzz->files[rnd_index]);
            unlink(fuzzer->fileName);
            return false;
        }

        if (files_writeToFd(dstfd, fuzzer->dynamicFile, fileSz) == false) {
            close(dstfd);
            unlink(fuzzer->fileName);
            return false;
        }
    }

    close(dstfd);

    pid_t pid = arch_fork(hfuzz);
    if (pid == -1) {
        PLOG_E("Couldn't fork");
        return false;
    }

    if (!pid) {
        /*
         * child performs the external file modifications
         */
        execl(hfuzz->externalCommand, hfuzz->externalCommand, fuzzer->fileName, NULL);
        PLOG_F("Couldn't execute '%s %s'", hfuzz->externalCommand, fuzzer->fileName);
        return false;
    }

    /*
     * parent waits until child is done fuzzing the input file
     */
    int childStatus;
    int flags = 0;
#if defined(__WNOTHREAD)
    flags |= __WNOTHREAD;
#endif                          /* defined(__WNOTHREAD) */
    while (wait4(pid, &childStatus, flags, NULL) != pid) ;
    if (WIFEXITED(childStatus)) {
        LOG_D("External command exited with status %d", WEXITSTATUS(childStatus));
        return true;
    }
    if (WIFSIGNALED(childStatus)) {
        LOG_E("External command terminated with signal %d", WTERMSIG(childStatus));
        return false;
    }
    LOG_F("External command terminated abnormally, status: %d", childStatus);
    return false;

    abort();                    /* NOTREACHED */
}
Beispiel #18
0
//SIGPIPE是正常的信号,对端断开后本端协议栈在向对端传送数据时,对端会返回TCP RST,导致本端抛出SIGPIPE信号
void init_daemon(char* cmd) 
{ 
	int pid;  
    char *buf = "This is a Daemon, wcdj\n";  
    char path[FILEPATH_MAX];
    getRealPath(path);
    strcat(path,"/");
	strcat(path,"pushserver.lock");
	pid = readPidFile(path);
	if(pid != -1)
	{
    	printf("The server is start ...\n");    	
    }    	    
    if(strcmp(cmd,"stop") == 0 && pid != -1){
    	closeServer(pid,0);
    	int status;
    	int w;
    	 do {
            w = waitpid(pid, &status, WUNTRACED | WCONTINUED);
            if (w == -1) { perror("waitpid"); exit(EXIT_FAILURE); }

            if (WIFEXITED(status)) {
                printf("exited, status=%d/n", WEXITSTATUS(status));
            } else if (WIFSIGNALED(status)) {
                printf("killed by signal %d/n", WTERMSIG(status));
            } else if (WIFSTOPPED(status)) {
                printf("stopped by signal %d/n", WSTOPSIG(status));
            } else if (WIFCONTINUED(status)) {
                printf("continued/n");
            }
        } while (!WIFEXITED(status) && !WIFSIGNALED(status));
    	exit(0);
    }    
    else if(strcmp(cmd,"restart") == 0 && pid != -1){
    	int status;
    	int w;
    	 do {
            w = waitpid(pid, &status, WUNTRACED | WCONTINUED);
            if (w == -1) { perror("waitpid"); exit(EXIT_FAILURE); }

            if (WIFEXITED(status)) {
                printf("exited, status=%d/n", WEXITSTATUS(status));
            } else if (WIFSIGNALED(status)) {
                printf("killed by signal %d/n", WTERMSIG(status));
            } else if (WIFSTOPPED(status)) {
                printf("stopped by signal %d/n", WSTOPSIG(status));
            } else if (WIFCONTINUED(status)) {
                printf("continued/n");
            }
        } while (!WIFEXITED(status) && !WIFSIGNALED(status));
    	
    }else if(pid != -1){
    	printf("The server is start ...\n");   
    	exit(0);
    }
  	
    /* 屏蔽一些有关控制终端操作的信号 
     * 防止在守护进程没有正常运转起来时,因控制终端受到干扰退出或挂起 
     */  
    signal(SIGINT,  SIG_IGN);// 终端中断  
    signal(SIGHUP,  SIG_IGN);// 连接挂断  
    signal(SIGQUIT, SIG_IGN);// 终端退出  
    signal(SIGPIPE, SIG_IGN);// 向无读进程的管道写数据  
    signal(SIGTTOU, SIG_IGN);// 后台程序尝试写操作  
    signal(SIGTTIN, SIG_IGN);// 后台程序尝试读操作  
    signal(SIGTERM, SIG_IGN);// 终止  
    
    struct rlimit        rl;
 	if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
        printf("%s: can't get file limit", "pushserver");
        
	int i; 
	/*
	pid=fork();
	if(pid>0) 
		exit(0);//是父进程,结束父进程 
	else if(pid< 0) 
		exit(1);//fork失败,退出 
	//是第一子进程,后台继续执行 
	setsid();//第一子进程成为新的会话组长和进程组长 
	//并与控制终端分离 
	pid=fork();
	if(pid>0) 
		exit(0);//是第一子进程,结束第一子进程 
	else if(pid< 0) 
		exit(1);//fork失败,退出 
		*/
	if ((pid = fork()) < 0)
        printf("%s: can't fork", cmd);
    else if (pid != 0) /* parent */{
    	printf("tuichuzhu\n");
    	   exit(0);	
    }
    printf("jinlaile\n");
     
        
    setsid();
         
	//是第二子进程,继续 
	//第二子进程不再是会话组长 
	
	main_pid = getpid();     
	writePidFile(path);
	     
	for(i=3;i< NOFILE;++i)//关闭打开的文件描述符 MAXFILE 65536
		close(i); 
		     
	/*
	// [3] set current path  
    char szPath[1024];  
    if(getcwd(szPath, sizeof(szPath)) == NULL)  
    {  
        perror("getcwd");  
        exit(1);  
    }  
    else  
    {  
        chdir(szPath);  
        printf("set current path succ [%s]\n", szPath);  
    }  
    */     
	//chdir("/tmp");//改变工作目录到/tmp 
	umask(0);//重设文件创建掩模 
	 // [6] set termianl signal  
	     
 	signal(SIGTERM, wait_close); 
	signal(SIGHUP, restart_server);
	     
	/*
     * Close all open file descriptors.
     */
    if (rl.rlim_max == RLIM_INFINITY)
        rl.rlim_max = 1024;
    for (i = 0; i < rl.rlim_max; i++)
        close(i);
     
    /*
     * Attach file descriptors 0, 1, and 2 to /dev/null.
     */     
    int fd0 = open("/dev/null", O_RDWR);
    int fd1 = dup(0);
    int fd2 = dup(0);
     
    /*
     * Initialize the log file.
     */     
    openlog("pushserver", LOG_CONS, LOG_DAEMON);
    if (fd0 != 0 || fd1 != 1 || fd2 != 2) {     
        syslog(LOG_ERR, "unexpected file descriptors %d %d %d",fd0, fd1, fd2);
        exit(1);
    }     
    syslog(LOG_DEBUG, "daem ok ");
           
	return; 
} 
Beispiel #19
0
static int exec_conf(void)
{
	int pipefd[2], stat, size;
	struct sigaction sa;
	sigset_t sset, osset;

	sigemptyset(&sset);
	sigaddset(&sset, SIGINT);
	sigprocmask(SIG_BLOCK, &sset, &osset);

	signal(SIGINT, SIG_DFL);

	sa.sa_handler = winch_handler;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = SA_RESTART;
	sigaction(SIGWINCH, &sa, NULL);

	*argptr++ = NULL;

	pipe(pipefd);
	pid = fork();
	if (pid == 0) {
		sigprocmask(SIG_SETMASK, &osset, NULL);
		dup2(pipefd[1], 2);
		close(pipefd[0]);
		close(pipefd[1]);
		execv(args[0], args);
		_exit(EXIT_FAILURE);
	}

	close(pipefd[1]);
	bufptr = input_buf;
	while (1) {
		size = input_buf + sizeof(input_buf) - bufptr;
		size = read(pipefd[0], bufptr, size);
		if (size <= 0) {
			if (size < 0) {
				if (errno == EINTR || errno == EAGAIN)
					continue;
				perror("read");
			}
			break;
		}
		bufptr += size;
	}
	*bufptr++ = 0;
	close(pipefd[0]);
	waitpid(pid, &stat, 0);

	if (do_resize) {
		init_wsize();
		do_resize = 0;
		sigprocmask(SIG_SETMASK, &osset, NULL);
		return -1;
	}
	if (WIFSIGNALED(stat)) {
		printf("\finterrupted(%d)\n", WTERMSIG(stat));
		exit(1);
	}
#if 0
	printf("\fexit state: %d\nexit data: '%s'\n", WEXITSTATUS(stat), input_buf);
	sleep(1);
#endif
	sigpending(&sset);
	if (sigismember(&sset, SIGINT)) {
		printf("\finterrupted\n");
		exit(1);
	}
	sigprocmask(SIG_SETMASK, &osset, NULL);

	return WEXITSTATUS(stat);
}
Beispiel #20
0
int
main( int argc, char **argv )
{
	int status, retval, num_tests = 1, tmp;
	int EventSet1 = PAPI_NULL;
	long long **values;
	long long elapsed_us, elapsed_cyc, elapsed_virt_us, elapsed_virt_cyc;
	char event_name[PAPI_MAX_STR_LEN];;
	const PAPI_hw_info_t *hw_info;
	const PAPI_component_info_t *cmpinfo;
	pid_t pid;

	/* Fork before doing anything with the PMU */

	setbuf(stdout,NULL);
	pid = fork(  );
	if ( pid < 0 )
		test_fail( __FILE__, __LINE__, "fork()", PAPI_ESYS );
	if ( pid == 0 )
		exit( wait_for_attach_and_loop(  ) );

	tests_quiet( argc, argv );	/* Set TESTS_QUIET variable */


	/* Master only process below here */

	retval = PAPI_library_init( PAPI_VER_CURRENT );
	if ( retval != PAPI_VER_CURRENT )
		test_fail_exit( __FILE__, __LINE__, "PAPI_library_init", retval );

	if ( ( cmpinfo = PAPI_get_component_info( 0 ) ) == NULL )
		test_fail_exit( __FILE__, __LINE__, "PAPI_get_component_info", 0 );

	if ( cmpinfo->attach == 0 )
		test_skip( __FILE__, __LINE__, "Platform does not support attaching",
				   0 );

	hw_info = PAPI_get_hardware_info(  );
	if ( hw_info == NULL )
		test_fail_exit( __FILE__, __LINE__, "PAPI_get_hardware_info", 0 );

	/* add PAPI_TOT_CYC and one of the events in PAPI_FP_INS, PAPI_FP_OPS or
	   PAPI_TOT_INS, depending on the availability of the event on the
	   platform */
	retval = PAPI_create_eventset(&EventSet1);
	if ( retval != PAPI_OK )
		test_fail_exit( __FILE__, __LINE__, "PAPI_attach", retval );

	/* Force addition of component */

	retval = PAPI_assign_eventset_component( EventSet1, 0 );
	if ( retval != PAPI_OK )
		test_fail( __FILE__, __LINE__, "PAPI_assign_eventset_component",
				   retval );

	/* The following call causes this test to fail for perf_events */

	retval = PAPI_attach( EventSet1, ( unsigned long ) pid );
	if ( retval != PAPI_OK )
		test_fail_exit( __FILE__, __LINE__, "PAPI_attach", retval );

	sprintf(event_name,"PAPI_TOT_CYC");

	retval = PAPI_add_event(EventSet1, PAPI_TOT_CYC);
	if ( retval != PAPI_OK )
		test_fail_exit( __FILE__, __LINE__, "PAPI_add_event", retval );
	retval = PAPI_add_event(EventSet1, PAPI_FP_INS);
	if ( retval == PAPI_ENOEVNT ) {
		test_warn( __FILE__, __LINE__, "PAPI_FP_INS", retval);
	} else if ( retval != PAPI_OK ) {
		test_fail_exit( __FILE__, __LINE__, "PAPI_add_event", retval );
	}
	
	values = allocate_test_space( 1, 2);

	elapsed_us = PAPI_get_real_usec(  );

	elapsed_cyc = PAPI_get_real_cyc(  );

	elapsed_virt_us = PAPI_get_virt_usec(  );

	elapsed_virt_cyc = PAPI_get_virt_cyc(  );

	printf("must_ptrace is %d\n",cmpinfo->attach_must_ptrace);
	pid_t  child = wait( &status );
	printf( "Debugger exited wait() with %d\n",child );
	  if (WIFSTOPPED( status ))
	    {
	      printf( "Child has stopped due to signal %d (%s)\n",
		      WSTOPSIG( status ), strsignal(WSTOPSIG( status )) );
	    }
	  if (WIFSIGNALED( status ))
	    {
	      printf( "Child %ld received signal %d (%s)\n",
		      (long)child,
		      WTERMSIG(status) , strsignal(WTERMSIG( status )) );
	    }
	printf("After %d\n",retval);

	retval = PAPI_start( EventSet1 );
	if ( retval != PAPI_OK )
		test_fail_exit( __FILE__, __LINE__, "PAPI_start", retval );

	printf("Continuing\n");
#if defined(__FreeBSD__)
	if ( ptrace( PT_CONTINUE, pid, (caddr_t) 1, 0 ) == -1 ) {
#else
	if ( ptrace( PTRACE_CONT, pid, NULL, NULL ) == -1 ) {
#endif
	  perror( "ptrace(PTRACE_CONT)" );
	  return 1;
	}


	do {
	  child = wait( &status );
	  printf( "Debugger exited wait() with %d\n", child);
	  if (WIFSTOPPED( status ))
	    {
	      printf( "Child has stopped due to signal %d (%s)\n",
		      WSTOPSIG( status ), strsignal(WSTOPSIG( status )) );
	    }
	  if (WIFSIGNALED( status ))
	    {
	      printf( "Child %ld received signal %d (%s)\n",
		      (long)child,
		      WTERMSIG(status) , strsignal(WTERMSIG( status )) );
	    }
	} while (!WIFEXITED( status ));

	printf("Child exited with value %d\n",WEXITSTATUS(status));
	if (WEXITSTATUS(status) != 0) 
	  test_fail_exit( __FILE__, __LINE__, "Exit status of child to attach to", PAPI_EMISC);

	retval = PAPI_stop( EventSet1, values[0] );
	if ( retval != PAPI_OK )
	  test_fail_exit( __FILE__, __LINE__, "PAPI_stop", retval );

	elapsed_virt_us = PAPI_get_virt_usec(  ) - elapsed_virt_us;

	elapsed_virt_cyc = PAPI_get_virt_cyc(  ) - elapsed_virt_cyc;

	elapsed_us = PAPI_get_real_usec(  ) - elapsed_us;

	elapsed_cyc = PAPI_get_real_cyc(  ) - elapsed_cyc;

	retval = PAPI_cleanup_eventset(EventSet1);
	if (retval != PAPI_OK)
	  test_fail_exit( __FILE__, __LINE__, "PAPI_cleanup_eventset", retval );

	retval = PAPI_destroy_eventset(&EventSet1);
	if (retval != PAPI_OK)
	  test_fail_exit( __FILE__, __LINE__, "PAPI_destroy_eventset", retval );

	printf( "Test case: 3rd party attach start, stop.\n" );
	printf( "-----------------------------------------------\n" );
	tmp = PAPI_get_opt( PAPI_DEFDOM, NULL );
	printf( "Default domain is: %d (%s)\n", tmp, stringify_all_domains( tmp ) );
	tmp = PAPI_get_opt( PAPI_DEFGRN, NULL );
	printf( "Default granularity is: %d (%s)\n", tmp,
			stringify_granularity( tmp ) );
	printf( "Using %d iterations of c += a*b\n", NUM_FLOPS );
	printf
		( "-------------------------------------------------------------------------\n" );

	printf( "Test type    : \t           1\n" );

	printf( TAB1, "PAPI_TOT_CYC : \t", ( values[0] )[0] );
	printf( TAB1, "PAPI_FP_INS  : \t", ( values[0] )[1] );
	printf( TAB1, "Real usec    : \t", elapsed_us );
	printf( TAB1, "Real cycles  : \t", elapsed_cyc );
	printf( TAB1, "Virt usec    : \t", elapsed_virt_us );
	printf( TAB1, "Virt cycles  : \t", elapsed_virt_cyc );

	printf
		( "-------------------------------------------------------------------------\n" );

	printf( "Verification: none\n" );

	test_pass( __FILE__, values, num_tests );
	exit( 1 );
}
Beispiel #21
0
int
pload (int tbl)
{
	int c = 0, i, status;
	
	if (verbose > 0)
	{
		fprintf (stderr, "Starting %d children to load %s",
			children, tdefs[tbl].comment);
	}
	for (c = 0; c < children; c++)
	{
		pids[c] = SPAWN ();
		if (pids[c] == -1)
		{
			perror ("Child loader not created");
			kill_load ();
			exit (-1);
		}
		else if (pids[c] == 0)	/* CHILD */
		{
			SET_HANDLER (stop_proc);
			verbose = 0;
			partial (tbl, c+1);
			exit (0);
		}
		else if (verbose > 0)			/* PARENT */
			fprintf (stderr, ".");
	}
	
	if (verbose > 0)
		fprintf (stderr, "waiting...");

	c = children;
	while (c)
	{
		i = WAIT (&status, pids[c - 1]);
		if (i == -1 && children)
		{
			if (errno == ECHILD)
				fprintf (stderr, "\nCould not wait on pid %d\n", pids[c - 1]);
			else if (errno == EINTR)
				fprintf (stderr, "\nProcess %d stopped abnormally\n", pids[c - 1]);
			else if (errno == EINVAL)
				fprintf (stderr, "\nProgram bug\n");
		}
		if (! WIFEXITED(status)) {
			(void) fprintf(stderr, "\nProcess %d: ", i);
			if (WIFSIGNALED(status)) {
				(void) fprintf(stderr, "rcvd signal %d\n",
					WTERMSIG(status));
				} else if (WIFSTOPPED(status)) {
				(void) fprintf(stderr, "stopped, signal %d\n",
					WSTOPSIG(status));
					}
				
			}
		c--;
	}

	if (verbose > 0)
		fprintf (stderr, "done\n");
	return (0);
}
Beispiel #22
0
/* Monitoring the subprocess end and get the return value */
static void *
monitor (void *arg)
{
  subprocess_t *p = arg;
  struct timespec start_time;

  /* Initializing the pipes () */
  int stdin_pipe[2];		/* '0' = child_read,  '1' = parent_write */
  int stdout_pipe[2];		/* '0' = parent_read, '1' = child_write */
  int stderr_pipe[2];		/* '0' = parent_read, '1' = child_write */

  CHECK_ERROR (((pipe (stdin_pipe) == -1) ||
		(pipe (stdout_pipe) == -1) ||
		(pipe (stderr_pipe) == -1)), "pipe initialization failed");

  /* We create a child process running the subprocess and we wait for
   * it to finish. If a timeout elapsed the child is killed. Waiting
   * is done using sigtimedwait(). Race condition is avoided by
   * blocking the SIGCHLD signal before fork() and storing it into the
   * buffer while starting the timer in a separate pthread. */

  /* Blocking SIGCHLD before forking */
  sigset_t mask;

  CHECK_ERROR ((sigemptyset (&mask) == -1), "sigemptyset failed");
  CHECK_ERROR ((sigaddset (&mask, SIGCHLD) == -1), "sigaddset failed");

  CHECK_ERROR ((sigprocmask (SIG_BLOCK, &mask, NULL) == -1),
	       "sigprocmask failed");

  /* Getting start time of the subprocess (profiling information) */
  CHECK_ERROR ((clock_gettime (CLOCK_MONOTONIC, &start_time) == -1),
	       "getting start time failed");

  /* Forking the process */
  CHECK_ERROR (((p->pid = fork ()) == -1), "fork failed");

  if (p->pid == 0)	/***** Child process *****/
    {
      /* TODO: What if the child_monitor fails miserably ? It should
       * be signaled in the parent stderr and not in the child
       * stderr. */
      CHECK_ERROR ((child_monitor (p,
				   stdin_pipe,
				   stdout_pipe,
				   stderr_pipe) == RETURN_FAILURE),
		   "child monitor failed");
    }
  else			    /***** Parent process *****/
    {
      int status;
      pthread_t watchdog_pthread, io_pthread;
      struct rusage usage;

      CHECK_ERROR ((close (stdin_pipe[0]) == -1), "close(stdin[0]) failed");
      CHECK_ERROR (((p->stdin = fdopen (stdin_pipe[1], "w")) == NULL),
		   "fdopen(stdin[1]) failed");

      CHECK_ERROR ((close (stdout_pipe[1]) == -1), "close(stdout[1]) failed");
      CHECK_ERROR (((p->stdout = fdopen (stdout_pipe[0], "r")) == NULL),
		   "fdopen(stdout[0]) failed");

      CHECK_ERROR ((close (stderr_pipe[1]) == -1), "close(stderr[1]) failed");
      CHECK_ERROR (((p->stderr = fdopen (stderr_pipe[0], "r")) == NULL),
		   "fdopen(stderr[0]) failed");

      /* Running a watchdog to timeout the subprocess */
      if ((p->limits) && (p->limits->timeout > 0))
	CHECK_ERROR ((pthread_create (&watchdog_pthread, NULL, watchdog, p) !=
		      0), "watchdog creation failed");

      /* Running the io monitor to watch stdout and stderr */
      CHECK_ERROR ((pthread_create (&io_pthread, NULL, io_monitor, p) != 0),
		   "io_monitor creation failed");

      p->status = RUNNING;

      /* Waiting for synchronization with monitored process */
      CHECK_ERROR (wait4 (p->pid, &status, 0, &usage) == -1, "wait failed");

      /* Filtering syscalls with ptrace */
      if ((p->limits != NULL) && (p->limits->syscalls[0] > 0))
	{
	  if (syscall_filter (p, &status, &usage) == RETURN_FAILURE)
	    goto fail;
	}

      /***** The subprocess is finished now *****/

      /* Getting end time of the subprocess (profiling information) */
      struct timespec tmp_time, end_time;

      CHECK_ERROR ((clock_gettime (CLOCK_MONOTONIC, &end_time) == -1),
		   "getting end time failed");
      tmp_time = timespec_diff (start_time, end_time);

      p->real_time_usec =
	(time_t) (tmp_time.tv_sec * 1000000 + tmp_time.tv_nsec / 1000);

      /* Finding out what the status and retval are really */
      if (WIFEXITED (status))
	{			/* Exited normally */
	  p->status = TERMINATED;
	  p->retval = WEXITSTATUS (status);	/* Return value */
	}
      else if (WIFSIGNALED (status))
	{
	  p->retval = WTERMSIG (status);	/* Kill signal */

	  if (p->status < TERMINATED)
	    {
	      /* Trying to guess why by looking at errno value */
	      switch (WTERMSIG (status))
		{
		case SIGSEGV:
		  p->status = MEMORYOUT;
		  break;

		default:
		  p->status = KILLED;
		}
	    }
	  /* FIXME: It may be interesting to store the termination signal
	   * into another variable and to 'p->retval = errno' */
	}
      else if (WIFSTOPPED (status))
	{
	  p->status = STOPPED;
	  p->retval = WSTOPSIG (status);	/* Stop signal */
	}
      else if (WIFCONTINUED (status))
	{
	  p->status = RUNNING;
	  p->retval = 0;	/* Process is still running */
	}

    fail:
      /* Cleaning the io_monitor */
      pthread_cancel (io_pthread);

      /* Cleaning the watchdog if not already exited */
      if ((p->limits) && (p->limits->timeout > 0))
	pthread_cancel (watchdog_pthread);

      /* Cleaning and setting the profile information */
      /* User time in us */
      p->user_time_usec =
	usage.ru_utime.tv_sec * 1000 + usage.ru_utime.tv_usec;

      /* System time in us */
      p->sys_time_usec =
	usage.ru_stime.tv_sec * 1000 + usage.ru_stime.tv_usec;

      /* Memory usage */
      p->memory_kbytes = usage.ru_maxrss;
    }

  return NULL;
}
Beispiel #23
0
int runProgram()
{
    //printf("runProgram()\n");
    if (global.params.verbose)
    {
        printf("%s", global.params.exefile);
        for (size_t i = 0; i < global.params.runargs_length; i++)
            printf(" %s", (char *)global.params.runargs[i]);
        printf("\n");
    }

    // Build argv[]
    Strings argv;

    argv.push(global.params.exefile);
    for (size_t i = 0; i < global.params.runargs_length; i++)
    {   char *a = global.params.runargs[i];

#if _WIN32
        // BUG: what about " appearing in the string?
        if (strchr(a, ' '))
        {   char *b = (char *)mem.malloc(3 + strlen(a));
            sprintf(b, "\"%s\"", a);
            a = b;
        }
#endif
        argv.push(a);
    }
    argv.push(NULL);

#if _WIN32
    char *ex = FileName::name(global.params.exefile);
    if (ex == global.params.exefile)
        ex = FileName::combine(".", ex);
    else
        ex = global.params.exefile;
    // spawnlp returns intptr_t in some systems, not int
    return spawnv(0,ex,argv.tdata());
#elif linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun
    pid_t childpid;
    int status;

    childpid = fork();
    if (childpid == 0)
    {
        char *fn = argv[0];
        if (!FileName::absolute(fn))
        {   // Make it "./fn"
            fn = FileName::combine(".", fn);
        }
        execv(fn, argv.tdata());
        perror(fn);             // failed to execute
        return -1;
    }

    waitpid(childpid, &status, 0);

    if (WIFEXITED(status))
    {
        status = WEXITSTATUS(status);
        //printf("--- errorlevel %d\n", status);
    }
    else if (WIFSIGNALED(status))
    {
        printf("--- killed by signal %d\n", WTERMSIG(status));
        status = 1;
    }
    return status;
#else
    assert(0);
#endif
}
Beispiel #24
0
int main(int args, char *argv[]){

	if(args<4){
		ToPipe("IE ERROR Not enough arguments.");
		return 1;
	}
	
	int TimeLimit, MemoryLimit, InputFileId, FileId;
	struct timeval start,finish;
    struct sigaction signalAction;
	pid_t w;
    int status;
    long long t_sec, t_usec;
    
    FileId = atoi(argv[1]), InputFileId = atoi(argv[2]), TimeLimit = atoi(argv[3]), MemoryLimit = atoi(argv[4]);
	
	signalAction.sa_flags = SA_NOCLDSTOP | SA_NOCLDWAIT;
	signalAction.sa_handler = signalHandler;
	
	if(sigaction(SIGALRM, &signalAction, NULL)==-1){
		ToPipe("IE ERROR Could not register handler for sigalrm");
		return 1;
	}
	if(sigaction(SIGXCPU, &signalAction, NULL)==-1){
		ToPipe("IE ERROR Could not register handler fo rSIGXCPU");
		return 1;
	}
	gettimeofday(&start,NULL);
    cpid = fork();
    if (cpid == -1) { perror("fork"); exit(EXIT_FAILURE); }

    if (cpid == 0) {            /* Code executed by child */
		
		pid_t ChildProcessId = getpid();
		passwd* UserDetails = getpwnam("nobody");
		char dir[10];
		sprintf(dir, "%s%d/",FILEPATH,FileId);
		//ToPipe(dir);
		if( chdir(dir) == -1){
			printf("%d", errno);
			ToPipe("IE ERROR Cannot change directory to that of file");
			return 1;
		}
		//ToPipe(get_current_dir_name());
		/*if(chroot(get_current_dir_name())!=0){
			ToPipe("IE ERROR Cannot jail the program");
			return 1;
		}*/
		
		if(( setpgid( ChildProcessId, ChildProcessId) ) == -1 ){
			ToPipe("IE ERROR process group could not be created\n");
			return 1;
		}
		
		if(UserDetails!=NULL){ 
			gid_t GroupId = UserDetails->pw_gid;
			if( GroupId > 0 ){
				setgid( GroupId );
			}
			else{
				ToPipe("IE ERROR Could not set groupid as groupid is invalid\n");
				return 1;
			}
			uid_t UserId = UserDetails->pw_uid;
			if( UserId > 0 ){
		 		setuid(UserId);
		 	}
			else{
				ToPipe("IE ERROR Failed to set userid as it is invalid\n");
				return 1;
			}
		} 
		else{ 
			ToPipe("IE ERROR No user id associated with user nobody\n");
			return 1; 
		}
		
		char InputFile[10], TestCaseFile[10], OutputFile[10];
		sprintf(InputFile, "main");
		sprintf(TestCaseFile, "%d.txt", InputFileId);
		sprintf(OutputFile, "%do.txt", InputFileId);
		if(freopen(TestCaseFile, "r", stdin)==NULL){
			ToPipe("IE ERROR Could not open test case file\n");
		}
		if(freopen(OutputFile, "w", stdout)==NULL){
			ToPipe("IE ERROR Could not open output file\n");
		}
		if(freopen("/dev/null", "w", stderr)==NULL){
			ToPipe("IE ERROR Could not redirect error stream to null\n");
		}
		setResourceLimitWrapper(TimeLimit, MemoryLimit);
		alarm(TimeLimit);
		if(execl(InputFile,InputFile,(char *) NULL) == -1){
			fclose(stdout);
			ToPipe("IE ERROR File not present or some other error.");
		}
		
	}
	else {                    /* Code executed by parent */

		struct rusage resourceUsage;
		w = wait4 (cpid, &status, NULL, &resourceUsage);
		
		gettimeofday(&finish,NULL);
		t_sec = finish.tv_sec-start.tv_sec;
		t_sec=finish.tv_sec-start.tv_sec;
		t_usec=finish.tv_usec-start.tv_usec;
		if(t_usec<0){
			t_sec--;
			t_usec+=1000000;
		}	
		
		timeval tv = resourceUsage.ru_utime;
		float SysTime = (float)(  tv.tv_sec * 1000000 + (int) tv.tv_usec ) / 1000000 ;
		float TimeUsed = (float)( t_sec * 1000000 + (int) t_usec ) / 1000000 ;
		
		if( WIFEXITED(status) == true ){
			if( WEXITSTATUS(status) !=0 ){
				ToPipe("RE NZEC");
			}
			else{
				ToPipe("AC");
			}
		}
		else if( WIFSIGNALED(status) == true ){
			if (WTERMSIG (status) == SIGKILL || WTERMSIG(status) == SIGALRM)
				ToPipe("TLE");
		    else if (WTERMSIG (status) == SIGXFSZ)
				ToPipe("RE SIGXFSZ");
			else if (WTERMSIG (status) == SIGSEGV)
				ToPipe("RE SIGSEGV");
			else if (WTERMSIG (status) == SIGFPE)
				ToPipe("RE SIGFPE");
			else if (WTERMSIG (status) == SIGABRT)
				ToPipe("RE SIGABRT");
		    else if (WTERMSIG (status) == SIGHUP)
				ToPipe("IE SIGHUP");
		    else if (WTERMSIG (status) == SIGPIPE)
				ToPipe("IE SIGPIPE");
		    else{
				ToPipe("RE OTHER");
				printf("%d\n", WTERMSIG(status));
			}
		}
		char tmp[10];
		sprintf(tmp, "%0.4f", TimeUsed);
		ToPipe(tmp);
		printf("%d %d\n", (int)tv.tv_sec, (int)tv.tv_usec);
	}
}
Beispiel #25
0
int master_loop(char **argv, char **environ) {

	uint64_t tmp_counter;

	struct timeval last_respawn;
	int last_respawn_rate = 0;

	int pid_found = 0;

	pid_t diedpid;
	int waitpid_status;

	uint8_t uwsgi_signal;

	time_t last_request_timecheck = 0, now = 0;
	uint64_t last_request_count = 0;

	pthread_t logger_thread;
	pthread_t cache_sweeper;
	pthread_t cache_udp_server;
	pthread_t channels_loop;

#ifdef UWSGI_UDP
	int udp_fd = -1;
#ifdef UWSGI_MULTICAST
	char *cluster_opt_buf = NULL;
	size_t cluster_opt_size = 4;
#endif
#endif



#ifdef UWSGI_SNMP
	int snmp_fd = -1;
#endif
	int i = 0;
	int rlen;

	int check_interval = 1;

	struct uwsgi_rb_timer *min_timeout;
	struct rb_root *rb_timers = uwsgi_init_rb_timer();


	if (uwsgi.procname_master) {
		uwsgi_set_processname(uwsgi.procname_master);
	}
	else if (uwsgi.procname) {
		uwsgi_set_processname(uwsgi.procname);
	}
	else if (uwsgi.auto_procname) {
		uwsgi_set_processname("uWSGI master");
	}


	uwsgi.current_time = uwsgi_now();

	uwsgi_unix_signal(SIGTSTP, suspend_resume_them_all);
	uwsgi_unix_signal(SIGHUP, grace_them_all);
	if (uwsgi.die_on_term) {
		uwsgi_unix_signal(SIGTERM, kill_them_all);
		uwsgi_unix_signal(SIGQUIT, reap_them_all);
	}
	else {
		uwsgi_unix_signal(SIGTERM, reap_them_all);
		uwsgi_unix_signal(SIGQUIT, kill_them_all);
	}
	uwsgi_unix_signal(SIGINT, kill_them_all);
	uwsgi_unix_signal(SIGUSR1, stats);
	if (uwsgi.auto_snapshot) {
		uwsgi_unix_signal(SIGURG, uwsgi_restore_auto_snapshot);
	}

	atexit(uwsgi_master_cleanup_hooks);

	uwsgi.master_queue = event_queue_init();

	/* route signals to workers... */
#ifdef UWSGI_DEBUG
	uwsgi_log("adding %d to signal poll\n", uwsgi.shared->worker_signal_pipe[0]);
#endif
	event_queue_add_fd_read(uwsgi.master_queue, uwsgi.shared->worker_signal_pipe[0]);

#ifdef UWSGI_SPOOLER
	if (uwsgi.spoolers) {
		event_queue_add_fd_read(uwsgi.master_queue, uwsgi.shared->spooler_signal_pipe[0]);
	}
#endif

	if (uwsgi.mules_cnt > 0) {
		event_queue_add_fd_read(uwsgi.master_queue, uwsgi.shared->mule_signal_pipe[0]);
	}

	if (uwsgi.log_master) {
		uwsgi.log_master_buf = uwsgi_malloc(uwsgi.log_master_bufsize);
		if (!uwsgi.threaded_logger) {
#ifdef UWSGI_DEBUG
			uwsgi_log("adding %d to master logging\n", uwsgi.shared->worker_log_pipe[0]);
#endif
			event_queue_add_fd_read(uwsgi.master_queue, uwsgi.shared->worker_log_pipe[0]);
		}
		else {
			if (pthread_create(&logger_thread, NULL, logger_thread_loop, NULL)) {
				uwsgi_error("pthread_create()");
				uwsgi_log("falling back to non-threaded logger...\n");
				event_queue_add_fd_read(uwsgi.master_queue, uwsgi.shared->worker_log_pipe[0]);
				uwsgi.threaded_logger = 0;
			}
		}

#ifdef UWSGI_ALARM
		// initialize the alarm subsystem
		uwsgi_alarms_init();
#endif
	}

#ifdef UWSGI_SSL
	uwsgi_start_legions();
#endif

	if (uwsgi.cache_max_items > 0 && !uwsgi.cache_no_expire) {
		if (pthread_create(&cache_sweeper, NULL, cache_sweeper_loop, NULL)) {
			uwsgi_error("pthread_create()");
			uwsgi_log("unable to run the cache sweeper !!!\n");
		}
		else {
			uwsgi_log("cache sweeper thread enabled\n");
		}
	}

	if (uwsgi.cache_max_items > 0 && uwsgi.cache_udp_server) {
                if (pthread_create(&cache_udp_server, NULL, cache_udp_server_loop, NULL)) {
                        uwsgi_error("pthread_create()");
                        uwsgi_log("unable to run the cache udp server !!!\n");
                }
                else {
                        uwsgi_log("cache udp server thread enabled\n");
                }
        }

	if (uwsgi.channels) {
		if (pthread_create(&channels_loop, NULL, uwsgi_channels_loop, NULL)) {
                        uwsgi_error("pthread_create()");
                        uwsgi_log("unable to run the channels dispatcher thread !!!\n");
                }
                else {
                        uwsgi_log("channels dispatcher thread enabled\n");
                }

	}


	uwsgi.wsgi_req->buffer = uwsgi.workers[0].cores[0].buffer;

	if (uwsgi.has_emperor) {
		event_queue_add_fd_read(uwsgi.master_queue, uwsgi.emperor_fd);
	}

	if (uwsgi.zerg_server) {
		uwsgi.zerg_server_fd = bind_to_unix(uwsgi.zerg_server, uwsgi.listen_queue, 0, 0);
		event_queue_add_fd_read(uwsgi.master_queue, uwsgi.zerg_server_fd);
		uwsgi_log("*** Zerg server enabled on %s ***\n", uwsgi.zerg_server);
	}

	if (uwsgi.stats) {
		char *tcp_port = strchr(uwsgi.stats, ':');
		if (tcp_port) {
			// disable deferred accept for this socket
			int current_defer_accept = uwsgi.no_defer_accept;
			uwsgi.no_defer_accept = 1;
			uwsgi.stats_fd = bind_to_tcp(uwsgi.stats, uwsgi.listen_queue, tcp_port);
			uwsgi.no_defer_accept = current_defer_accept;
		}
		else {
			uwsgi.stats_fd = bind_to_unix(uwsgi.stats, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
		}

		event_queue_add_fd_read(uwsgi.master_queue, uwsgi.stats_fd);
		uwsgi_log("*** Stats server enabled on %s fd: %d ***\n", uwsgi.stats, uwsgi.stats_fd);
	}


	if (uwsgi.requested_stats_pushers) {
		if (!uwsgi_thread_new(uwsgi_stats_pusher_loop)) {
			uwsgi_log("!!! unable to spawn stats pusher thread !!!\n");
			exit(1);
		}
	}

#ifdef UWSGI_UDP
	if (uwsgi.udp_socket) {
		udp_fd = bind_to_udp(uwsgi.udp_socket, 0, 0);
		if (udp_fd < 0) {
			uwsgi_log("unable to bind to udp socket. SNMP and cluster management services will be disabled.\n");
		}
		else {
			uwsgi_log("UDP server enabled.\n");
			event_queue_add_fd_read(uwsgi.master_queue, udp_fd);
		}
	}

#ifdef UWSGI_MULTICAST
	if (uwsgi.cluster) {
		event_queue_add_fd_read(uwsgi.master_queue, uwsgi.cluster_fd);
		cluster_opt_buf = uwsgi_setup_clusterbuf(&cluster_opt_size);
	}
#endif
#endif

#ifdef UWSGI_SNMP
	snmp_fd = uwsgi_setup_snmp();
#endif

	if (uwsgi.cheap) {
		uwsgi_add_sockets_to_queue(uwsgi.master_queue, -1);
		for (i = 1; i <= uwsgi.numproc; i++) {
			uwsgi.workers[i].cheaped = 1;
		}
		uwsgi_log("cheap mode enabled: waiting for socket connection...\n");
	}


	// spawn mules
	for (i = 0; i < uwsgi.mules_cnt; i++) {
		size_t mule_patch_size = 0;
		uwsgi.mules[i].patch = uwsgi_string_get_list(&uwsgi.mules_patches, i, &mule_patch_size);
		uwsgi_mule(i + 1);
	}

	// spawn gateways
	for (i = 0; i < ushared->gateways_cnt; i++) {
		if (ushared->gateways[i].pid == 0) {
			gateway_respawn(i);
		}
	}

	// spawn daemons
	uwsgi_daemons_spawn_all();

	// first subscription
	uwsgi_subscribe_all(0, 1);

	// sync the cache store if needed
	if (uwsgi.cache_store && uwsgi.cache_filesize) {
		if (msync(uwsgi.cache_items, uwsgi.cache_filesize, MS_ASYNC)) {
			uwsgi_error("msync()");
		}
	}

	if (uwsgi.queue_store && uwsgi.queue_filesize) {
		if (msync(uwsgi.queue_header, uwsgi.queue_filesize, MS_ASYNC)) {
			uwsgi_error("msync()");
		}
	}

	// update touches timestamps
	uwsgi_check_touches(uwsgi.touch_reload);
	uwsgi_check_touches(uwsgi.touch_logrotate);
	uwsgi_check_touches(uwsgi.touch_logreopen);

	// setup cheaper algos
	uwsgi.cheaper_algo = uwsgi_cheaper_algo_spare;
	if (uwsgi.requested_cheaper_algo) {
		uwsgi.cheaper_algo = NULL;
		struct uwsgi_cheaper_algo *uca = uwsgi.cheaper_algos;
		while (uca) {
			if (!strcmp(uca->name, uwsgi.requested_cheaper_algo)) {
				uwsgi.cheaper_algo = uca->func;
				break;
			}
			uca = uca->next;
		}

		if (!uwsgi.cheaper_algo) {
			uwsgi_log("unable to find requested cheaper algorithm, falling back to spare\n");
			uwsgi.cheaper_algo = uwsgi_cheaper_algo_spare;
		}

	}

	// here really starts the master loop

	for (;;) {
		//uwsgi_log("uwsgi.ready_to_reload %d %d\n", uwsgi.ready_to_reload, uwsgi.numproc);

		// run master_cycle hook for every plugin
		for (i = 0; i < uwsgi.gp_cnt; i++) {
			if (uwsgi.gp[i]->master_cycle) {
				uwsgi.gp[i]->master_cycle();
			}
		}
		for (i = 0; i < 256; i++) {
			if (uwsgi.p[i]->master_cycle) {
				uwsgi.p[i]->master_cycle();
			}
		}

		uwsgi_daemons_smart_check();

		if (uwsgi.to_outworld) {
			//uwsgi_log("%d/%d\n", uwsgi.lazy_respawned, uwsgi.numproc);
			if (uwsgi.lazy_respawned >= uwsgi.marked_workers || uwsgi.lazy_respawned >= uwsgi.numproc) {
				uwsgi.to_outworld = 0;
				uwsgi.master_mercy = 0;
				uwsgi.lazy_respawned = 0;
			}
		}


		if (uwsgi_master_check_mercy())
			return 0;

		if (uwsgi.respawn_workers) {
			for (i = 1; i <= uwsgi.respawn_workers; i++) {
				if (uwsgi_respawn_worker(i))
					return 0;
			}

			uwsgi.respawn_workers = 0;
		}

		if (uwsgi.restore_snapshot) {
			uwsgi_master_restore_snapshot();
			continue;
		}

		// cheaper management
		if (uwsgi.cheaper && !uwsgi.cheap && !uwsgi.to_heaven && !uwsgi.to_hell && !uwsgi.to_outworld && !uwsgi.workers[0].suspended) {
			if (!uwsgi_calc_cheaper())
				return 0;
		}

		if ((uwsgi.cheap || uwsgi.ready_to_die >= uwsgi.marked_workers || uwsgi.ready_to_die >= uwsgi.numproc) && uwsgi.to_hell) {
			// call a series of waitpid to ensure all processes (gateways, mules and daemons) are dead
			for (i = 0; i < (ushared->gateways_cnt + uwsgi.daemons_cnt + uwsgi.mules_cnt); i++) {
				diedpid = waitpid(WAIT_ANY, &waitpid_status, WNOHANG);
			}

			uwsgi_log("goodbye to uWSGI.\n");
			exit(0);
		}

		if ((uwsgi.cheap || uwsgi.ready_to_reload >= uwsgi.marked_workers || uwsgi.ready_to_reload >= uwsgi.numproc) && uwsgi.to_heaven) {
			uwsgi_reload(argv);
			// never here (unless in shared library mode)
			return -1;
		}

		diedpid = waitpid(WAIT_ANY, &waitpid_status, WNOHANG);
		if (diedpid == -1) {
			if (errno == ECHILD) {
				// something did not work as expected, just assume all has been cleared
				if (uwsgi.to_heaven) {
					uwsgi.ready_to_reload = uwsgi.numproc;
					continue;
				}
				else if (uwsgi.to_hell) {
					uwsgi.ready_to_die = uwsgi.numproc;
					continue;
				}
				else if (uwsgi.to_outworld) {
					uwsgi.lazy_respawned = uwsgi.numproc;
					uwsgi_log("*** no workers to reload found ***\n");
					continue;
				}
				diedpid = 0;
			}
			else {
				uwsgi_error("waitpid()");
				/* here is better to reload all the uWSGI stack */
				uwsgi_log("something horrible happened...\n");
				reap_them_all(0);
				exit(1);
			}
		}

		if (diedpid == 0) {

			/* all processes ok, doing status scan after N seconds */
			check_interval = uwsgi.shared->options[UWSGI_OPTION_MASTER_INTERVAL];
			if (!check_interval)
				check_interval = 1;


			// add unregistered file monitors
			// locking is not needed as monitors can only increase
			for (i = 0; i < ushared->files_monitored_cnt; i++) {
				if (!ushared->files_monitored[i].registered) {
					ushared->files_monitored[i].fd = event_queue_add_file_monitor(uwsgi.master_queue, ushared->files_monitored[i].filename, &ushared->files_monitored[i].id);
					ushared->files_monitored[i].registered = 1;
				}
			}


			// add unregistered timers
			// locking is not needed as timers can only increase
			for (i = 0; i < ushared->timers_cnt; i++) {
				if (!ushared->timers[i].registered) {
					ushared->timers[i].fd = event_queue_add_timer(uwsgi.master_queue, &ushared->timers[i].id, ushared->timers[i].value);
					ushared->timers[i].registered = 1;
				}
			}

			// add unregistered rb_timers
			// locking is not needed as rb_timers can only increase
			for (i = 0; i < ushared->rb_timers_cnt; i++) {
				if (!ushared->rb_timers[i].registered) {
					ushared->rb_timers[i].uwsgi_rb_timer = uwsgi_add_rb_timer(rb_timers, uwsgi_now() + ushared->rb_timers[i].value, &ushared->rb_timers[i]);
					ushared->rb_timers[i].registered = 1;
				}
			}

			int interesting_fd = -1;

			if (ushared->rb_timers_cnt > 0) {
				min_timeout = uwsgi_min_rb_timer(rb_timers);
				if (min_timeout == NULL) {
					check_interval = uwsgi.shared->options[UWSGI_OPTION_MASTER_INTERVAL];
				}
				else {
					check_interval = min_timeout->key - uwsgi_now();
					if (check_interval <= 0) {
						expire_rb_timeouts(rb_timers);
						check_interval = 0;
					}
				}
			}

			// wait for event
			rlen = event_queue_wait(uwsgi.master_queue, check_interval, &interesting_fd);

			if (rlen == 0) {
				if (ushared->rb_timers_cnt > 0) {
					expire_rb_timeouts(rb_timers);
				}
			}


			// check uwsgi-cron table
			if (ushared->cron_cnt) {
				uwsgi_manage_signal_cron(uwsgi_now());
			}

			if (uwsgi.crons) {
				uwsgi_manage_command_cron(uwsgi_now());
			}


			// check for probes
			if (ushared->probes_cnt > 0) {
				uwsgi_lock(uwsgi.probe_table_lock);
				for (i = 0; i < ushared->probes_cnt; i++) {
					if (interesting_fd == -1) {
						// increment cycles
						ushared->probes[i].cycles++;
					}
					if (ushared->probes[i].func(interesting_fd, &ushared->probes[i])) {
						uwsgi_route_signal(ushared->probes[i].sig);
					}
				}
				uwsgi_unlock(uwsgi.probe_table_lock);
			}

			if (rlen > 0) {

				if (uwsgi.log_master && !uwsgi.threaded_logger) {
					if (interesting_fd == uwsgi.shared->worker_log_pipe[0]) {
						uwsgi_master_log();
						goto health_cycle;
					}
				}

				if (uwsgi.stats && uwsgi.stats_fd > -1) {
					if (interesting_fd == uwsgi.stats_fd) {
						uwsgi_send_stats(uwsgi.stats_fd, uwsgi_master_generate_stats);
						goto health_cycle;
					}
				}

				if (uwsgi.zerg_server) {
					if (interesting_fd == uwsgi.zerg_server_fd) {
						uwsgi_manage_zerg(uwsgi.zerg_server_fd, 0, NULL);
						goto health_cycle;
					}
				}

				if (uwsgi.has_emperor) {
					if (interesting_fd == uwsgi.emperor_fd) {
						uwsgi_master_manage_emperor();
						goto health_cycle;
					}
				}


				if (uwsgi.cheap) {
					int found = 0;
					struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
					while (uwsgi_sock) {
						if (interesting_fd == uwsgi_sock->fd) {
							found = 1;
							uwsgi.cheap = 0;
							uwsgi_del_sockets_from_queue(uwsgi.master_queue);
							int needed = uwsgi.numproc;
							if (uwsgi.cheaper) {
								needed = uwsgi.cheaper_count;
							}
							for (i = 1; i <= needed; i++) {
								if (uwsgi_respawn_worker(i))
									return 0;
							}
							break;
						}
						uwsgi_sock = uwsgi_sock->next;
					}
					// here is better to continue instead going to health_cycle
					if (found)
						continue;
				}
#ifdef UWSGI_SNMP
				if (uwsgi.snmp_addr && interesting_fd == snmp_fd) {
					uwsgi_master_manage_snmp(snmp_fd);
					goto health_cycle;
				}
#endif

#ifdef UWSGI_UDP
				if (uwsgi.udp_socket && interesting_fd == udp_fd) {
					uwsgi_master_manage_udp(udp_fd);
					goto health_cycle;
				}

#ifdef UWSGI_MULTICAST
				if (interesting_fd == uwsgi.cluster_fd) {

					if (uwsgi_get_dgram(uwsgi.cluster_fd, &uwsgi.workers[0].cores[0].req)) {
						goto health_cycle;
					}

					manage_cluster_message(cluster_opt_buf, cluster_opt_size);

					goto health_cycle;
				}
#endif

#endif


				int next_iteration = 0;

				uwsgi_lock(uwsgi.fmon_table_lock);
				for (i = 0; i < ushared->files_monitored_cnt; i++) {
					if (ushared->files_monitored[i].registered) {
						if (interesting_fd == ushared->files_monitored[i].fd) {
							struct uwsgi_fmon *uf = event_queue_ack_file_monitor(uwsgi.master_queue, interesting_fd);
							// now call the file_monitor handler
							if (uf)
								uwsgi_route_signal(uf->sig);
							break;
						}
					}
				}

				uwsgi_unlock(uwsgi.fmon_table_lock);
				if (next_iteration)
					goto health_cycle;;

				next_iteration = 0;

				uwsgi_lock(uwsgi.timer_table_lock);
				for (i = 0; i < ushared->timers_cnt; i++) {
					if (ushared->timers[i].registered) {
						if (interesting_fd == ushared->timers[i].fd) {
							struct uwsgi_timer *ut = event_queue_ack_timer(interesting_fd);
							// now call the file_monitor handler
							if (ut)
								uwsgi_route_signal(ut->sig);
							break;
						}
					}
				}
				uwsgi_unlock(uwsgi.timer_table_lock);
				if (next_iteration)
					goto health_cycle;;


				// check for worker signal
				if (interesting_fd == uwsgi.shared->worker_signal_pipe[0]) {
					rlen = read(interesting_fd, &uwsgi_signal, 1);
					if (rlen < 0) {
						uwsgi_error("read()");
					}
					else if (rlen > 0) {
#ifdef UWSGI_DEBUG
						uwsgi_log_verbose("received uwsgi signal %d from a worker\n", uwsgi_signal);
#endif
						uwsgi_route_signal(uwsgi_signal);
					}
					else {
						uwsgi_log_verbose("lost connection with worker %d\n", i);
						close(interesting_fd);
					}
					goto health_cycle;
				}

#ifdef UWSGI_SPOOLER
				// check for spooler signal
				if (uwsgi.spoolers) {
					if (interesting_fd == uwsgi.shared->spooler_signal_pipe[0]) {
						rlen = read(interesting_fd, &uwsgi_signal, 1);
						if (rlen < 0) {
							uwsgi_error("read()");
						}
						else if (rlen > 0) {
#ifdef UWSGI_DEBUG
							uwsgi_log_verbose("received uwsgi signal %d from a spooler\n", uwsgi_signal);
#endif
							uwsgi_route_signal(uwsgi_signal);
						}
						else {
							uwsgi_log_verbose("lost connection with the spooler\n");
							close(interesting_fd);
						}
						goto health_cycle;
					}

				}
#endif

				// check for mules signal
				if (uwsgi.mules_cnt > 0) {
					if (interesting_fd == uwsgi.shared->mule_signal_pipe[0]) {
						rlen = read(interesting_fd, &uwsgi_signal, 1);
						if (rlen < 0) {
							uwsgi_error("read()");
						}
						else if (rlen > 0) {
#ifdef UWSGI_DEBUG
							uwsgi_log_verbose("received uwsgi signal %d from a mule\n", uwsgi_signal);
#endif
							uwsgi_route_signal(uwsgi_signal);
						}
						else {
							uwsgi_log_verbose("lost connection with a mule\n");
							close(interesting_fd);
						}
						goto health_cycle;
					}

				}


			}

health_cycle:
			now = uwsgi_now();
			if (now - uwsgi.current_time < 1) {
				continue;
			}
			uwsgi.current_time = now;

			// checking logsize
			if (uwsgi.logfile) {
				uwsgi_check_logrotate();
			}

			// this will be incremented at (more or less) regular intervals
			uwsgi.master_cycles++;

			// recalculate requests counter on race conditions risky configurations
			// a bit of inaccuracy is better than locking;)

			if (uwsgi.numproc > 1) {
				tmp_counter = 0;
				for (i = 1; i < uwsgi.numproc + 1; i++)
					tmp_counter += uwsgi.workers[i].requests;
				uwsgi.workers[0].requests = tmp_counter;
			}

			if (uwsgi.idle > 0 && !uwsgi.cheap) {
				uwsgi.current_time = uwsgi_now();
				if (!last_request_timecheck)
					last_request_timecheck = uwsgi.current_time;

				int busy_workers = 0;
				for (i = 1; i <= uwsgi.numproc; i++) {
					if (uwsgi.workers[i].cheaped == 0 && uwsgi.workers[i].pid > 0) {
						if (uwsgi.workers[i].busy == 1) {
							busy_workers = 1;
							break;
						}
					}
				}

				if (last_request_count != uwsgi.workers[0].requests) {
					last_request_timecheck = uwsgi.current_time;
					last_request_count = uwsgi.workers[0].requests;
				}
				// a bit of over-engeneering to avoid clock skews
				else if (last_request_timecheck < uwsgi.current_time && (uwsgi.current_time - last_request_timecheck > uwsgi.idle) && !busy_workers) {
					uwsgi_log("workers have been inactive for more than %d seconds (%llu-%llu)\n", uwsgi.idle, (unsigned long long) uwsgi.current_time, (unsigned long long) last_request_timecheck);
					uwsgi.cheap = 1;
					if (uwsgi.die_on_idle) {
						if (uwsgi.has_emperor) {
							char byte = 22;
							if (write(uwsgi.emperor_fd, &byte, 1) != 1) {
								uwsgi_error("write()");
								kill_them_all(0);
							}
						}
						else {
							kill_them_all(0);
						}
						continue;
					}
					for (i = 1; i <= uwsgi.numproc; i++) {
						uwsgi.workers[i].cheaped = 1;
						if (uwsgi.workers[i].pid == 0)
							continue;
						kill(uwsgi.workers[i].pid, SIGKILL);
						if (waitpid(uwsgi.workers[i].pid, &waitpid_status, 0) < 0) {
							if (errno != ECHILD)
								uwsgi_error("waitpid()");
						}
					}
					uwsgi_add_sockets_to_queue(uwsgi.master_queue, -1);
					uwsgi_log("cheap mode enabled: waiting for socket connection...\n");
					last_request_timecheck = 0;
					continue;
				}
			}

			check_interval = uwsgi.shared->options[UWSGI_OPTION_MASTER_INTERVAL];
			if (!check_interval)
				check_interval = 1;


			// get listen_queue status
			struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
			while (uwsgi_sock) {
				if (uwsgi_sock->family == AF_INET) {
					uwsgi_sock->queue = uwsgi_get_tcp_info(uwsgi_sock->fd);
				}
#ifdef __linux__
#ifdef SIOBKLGQ
				else if (uwsgi_sock->family == AF_UNIX) {
					uwsgi_sock->queue = get_linux_unbit_SIOBKLGQ(uwsgi_sock->fd);
				}
#endif
#endif
				uwsgi_sock = uwsgi_sock->next;
			}

			for (i = 1; i <= uwsgi.numproc; i++) {
				/* first check for harakiri */
				if (uwsgi.workers[i].harakiri > 0) {
					if (uwsgi.workers[i].harakiri < (time_t) uwsgi.current_time) {
						trigger_harakiri(i);
					}
				}
				/* then user-defined harakiri */
				if (uwsgi.workers[i].user_harakiri > 0) {
					if (uwsgi.workers[i].user_harakiri < (time_t) uwsgi.current_time) {
						trigger_harakiri(i);
					}
				}
				// then for evil memory checkers
				if (uwsgi.evil_reload_on_as) {
					if ((rlim_t) uwsgi.workers[i].vsz_size >= uwsgi.evil_reload_on_as) {
						uwsgi_log("*** EVIL RELOAD ON WORKER %d ADDRESS SPACE: %lld (pid: %d) ***\n", i, (long long) uwsgi.workers[i].vsz_size, uwsgi.workers[i].pid);
						kill(uwsgi.workers[i].pid, SIGKILL);
						uwsgi.workers[i].vsz_size = 0;
					}
				}
				if (uwsgi.evil_reload_on_rss) {
					if ((rlim_t) uwsgi.workers[i].rss_size >= uwsgi.evil_reload_on_rss) {
						uwsgi_log("*** EVIL RELOAD ON WORKER %d RSS: %lld (pid: %d) ***\n", i, (long long) uwsgi.workers[i].rss_size, uwsgi.workers[i].pid);
						kill(uwsgi.workers[i].pid, SIGKILL);
						uwsgi.workers[i].rss_size = 0;
					}
				}

				// need to find a better way
				//uwsgi.workers[i].last_running_time = uwsgi.workers[i].running_time;
			}

			for (i = 0; i < ushared->gateways_cnt; i++) {
				if (ushared->gateways_harakiri[i] > 0) {
					if (ushared->gateways_harakiri[i] < (time_t) uwsgi.current_time) {
						if (ushared->gateways[i].pid > 0) {
							kill(ushared->gateways[i].pid, SIGKILL);
						}
						ushared->gateways_harakiri[i] = 0;
					}
				}
			}

			for (i = 0; i < uwsgi.mules_cnt; i++) {
				if (uwsgi.mules[i].harakiri > 0) {
					if (uwsgi.mules[i].harakiri < (time_t) uwsgi.current_time) {
						uwsgi_log("*** HARAKIRI ON MULE %d HANDLING SIGNAL %d (pid: %d) ***\n", i + 1, uwsgi.mules[i].signum, uwsgi.mules[i].pid);
						kill(uwsgi.mules[i].pid, SIGKILL);
						uwsgi.mules[i].harakiri = 0;
					}
				}
			}
#ifdef UWSGI_SPOOLER
			struct uwsgi_spooler *uspool = uwsgi.spoolers;
			while (uspool) {
				if (uspool->harakiri > 0 && uspool->harakiri < (time_t) uwsgi.current_time) {
					uwsgi_log("*** HARAKIRI ON THE SPOOLER (pid: %d) ***\n", uspool->pid);
					kill(uspool->pid, SIGKILL);
					uspool->harakiri = 0;
				}
				uspool = uspool->next;
			}
#endif

#ifdef __linux__
#ifdef MADV_MERGEABLE
			if (uwsgi.linux_ksm > 0 && (uwsgi.master_cycles % uwsgi.linux_ksm) == 0) {
				uwsgi_linux_ksm_map();
			}
#endif
#endif

#ifdef UWSGI_UDP
			// check for cluster nodes
			master_check_cluster_nodes();

			// reannounce myself every 10 cycles
			if (uwsgi.cluster && uwsgi.cluster_fd >= 0 && !uwsgi.cluster_nodes && (uwsgi.master_cycles % 10) == 0) {
				uwsgi_cluster_add_me();
			}

			// resubscribe every 10 cycles by default
			if (( (uwsgi.subscriptions || uwsgi.subscriptions2) && ((uwsgi.master_cycles % uwsgi.subscribe_freq) == 0 || uwsgi.master_cycles == 1)) && !uwsgi.to_heaven && !uwsgi.to_hell && !uwsgi.workers[0].suspended) {
				uwsgi_subscribe_all(0, 0);
			}

#endif

			if (uwsgi.cache_store && uwsgi.cache_filesize && uwsgi.cache_store_sync && ((uwsgi.master_cycles % uwsgi.cache_store_sync) == 0)) {
				if (msync(uwsgi.cache_items, uwsgi.cache_filesize, MS_ASYNC)) {
					uwsgi_error("msync()");
				}
			}

			if (uwsgi.queue_store && uwsgi.queue_filesize && uwsgi.queue_store_sync && ((uwsgi.master_cycles % uwsgi.queue_store_sync) == 0)) {
				if (msync(uwsgi.queue_header, uwsgi.queue_filesize, MS_ASYNC)) {
					uwsgi_error("msync()");
				}
			}

			// check touch_reload
			if (!uwsgi.to_heaven && !uwsgi.to_hell) {
				char *touched = uwsgi_check_touches(uwsgi.touch_reload);
				if (touched) {
					uwsgi_log("*** %s has been touched... grace them all !!! ***\n", touched);
					uwsgi_block_signal(SIGHUP);
					grace_them_all(0);
					uwsgi_unblock_signal(SIGHUP);
				}
			}

			continue;

		}

		// no one died
		if (diedpid <= 0)
			continue;

		// check for deadlocks first
		uwsgi_deadlock_check(diedpid);

		// reload gateways and daemons only on normal workflow (+outworld status)
		if (!uwsgi.to_heaven && !uwsgi.to_hell) {

#ifdef UWSGI_SPOOLER
			/* reload the spooler */
			struct uwsgi_spooler *uspool = uwsgi.spoolers;
			pid_found = 0;
			while (uspool) {
				if (uspool->pid > 0 && diedpid == uspool->pid) {
					uwsgi_log("OOOPS the spooler is no more...trying respawn...\n");
					uspool->respawned++;
					uspool->pid = spooler_start(uspool);
					pid_found = 1;
					break;
				}
				uspool = uspool->next;
			}

			if (pid_found)
				continue;
#endif

			pid_found = 0;
			for (i = 0; i < uwsgi.mules_cnt; i++) {
				if (uwsgi.mules[i].pid == diedpid) {
					uwsgi_log("OOOPS mule %d (pid: %d) crippled...trying respawn...\n", i + 1, uwsgi.mules[i].pid);
					uwsgi_mule(i + 1);
					pid_found = 1;
					break;
				}
			}

			if (pid_found)
				continue;


			/* reload the gateways */
			pid_found = 0;
			for (i = 0; i < ushared->gateways_cnt; i++) {
				if (ushared->gateways[i].pid == diedpid) {
					gateway_respawn(i);
					pid_found = 1;
					break;
				}
			}

			if (pid_found)
				continue;

			/* reload the daemons */
			pid_found = uwsgi_daemon_check_pid_reload(diedpid);

			if (pid_found)
				continue;

		}


		/* What happens here ?

		   case 1) the diedpid is not a worker, report it and continue
		   case 2) the diedpid is a worker and we are not in a reload procedure -> reload it
		   case 3) the diedpid is a worker and we are in graceful reload -> uwsgi.ready_to_reload++ and continue
		   case 3) the diedpid is a worker and we are in brutal reload -> uwsgi.ready_to_die++ and continue


		 */

		uwsgi.mywid = find_worker_id(diedpid);
		if (uwsgi.mywid <= 0) {
			// check spooler, mules, gateways and daemons
#ifdef UWSGI_SPOOLER
			struct uwsgi_spooler *uspool = uwsgi.spoolers;
			while (uspool) {
				if (uspool->pid > 0 && diedpid == uspool->pid) {
					uwsgi_log("spooler (pid: %d) annihilated\n", (int) diedpid);
					goto next;
				}
				uspool = uspool->next;
			}
#endif

			for (i = 0; i < uwsgi.mules_cnt; i++) {
				if (uwsgi.mules[i].pid == diedpid) {
					uwsgi_log("mule %d (pid: %d) annihilated\n", i + 1, (int) diedpid);
					goto next;
				}
			}

			for (i = 0; i < ushared->gateways_cnt; i++) {
				if (ushared->gateways[i].pid == diedpid) {
					uwsgi_log("gateway %d (%s, pid: %d) annihilated\n", i + 1, ushared->gateways[i].fullname, (int) diedpid);
					goto next;
				}
			}

			if (uwsgi_daemon_check_pid_death(diedpid))
				goto next;

			if (WIFEXITED(waitpid_status)) {
				uwsgi_log("subprocess %d exited with code %d\n", (int) diedpid, WEXITSTATUS(waitpid_status));
			}
			else if (WIFSIGNALED(waitpid_status)) {
				uwsgi_log("subprocess %d exited by signal %d\n", (int) diedpid, WTERMSIG(waitpid_status));
			}
			else if (WIFSTOPPED(waitpid_status)) {
				uwsgi_log("subprocess %d stopped\n", (int) diedpid);
			}
next:
			continue;
		}


		// ok a worker died...
		if (uwsgi.to_heaven) {
			uwsgi.ready_to_reload++;
			uwsgi.workers[uwsgi.mywid].pid = 0;
			// only to be safe :P
			uwsgi.workers[uwsgi.mywid].harakiri = 0;
			continue;
		}
		else if (uwsgi.to_hell) {
			uwsgi.ready_to_die++;
			uwsgi.workers[uwsgi.mywid].pid = 0;
			// only to be safe :P
			uwsgi.workers[uwsgi.mywid].harakiri = 0;
			continue;
		}
		else if (uwsgi.to_outworld) {
			uwsgi.lazy_respawned++;
			uwsgi.workers[uwsgi.mywid].destroy = 0;
			uwsgi.workers[uwsgi.mywid].pid = 0;
			// only to be safe :P
			uwsgi.workers[uwsgi.mywid].harakiri = 0;
		}

		if (WIFEXITED(waitpid_status) && WEXITSTATUS(waitpid_status) == UWSGI_FAILED_APP_CODE) {
			uwsgi_log("OOPS ! failed loading app in worker %d (pid %d) :( trying again...\n", uwsgi.mywid, (int) diedpid);
		}
		else if (WIFEXITED(waitpid_status) && WEXITSTATUS(waitpid_status) == UWSGI_DE_HIJACKED_CODE) {
			uwsgi_log("...restoring worker %d (pid: %d)...\n", uwsgi.mywid, (int) diedpid);
		}
		else if (WIFEXITED(waitpid_status) && WEXITSTATUS(waitpid_status) == UWSGI_EXCEPTION_CODE) {
			uwsgi_log("... monitored exception detected, respawning worker %d (pid: %d)...\n", uwsgi.mywid, (int) diedpid);
		}
		else if (WIFEXITED(waitpid_status) && WEXITSTATUS(waitpid_status) == UWSGI_QUIET_CODE) {
			// noop
		}
		else if (uwsgi.workers[uwsgi.mywid].manage_next_request) {
			if (WIFSIGNALED(waitpid_status)) {
				uwsgi_log("DAMN ! worker %d (pid: %d) died, killed by signal %d :( trying respawn ...\n", uwsgi.mywid, (int) diedpid, (int) WTERMSIG(waitpid_status));
			}
			else {
				uwsgi_log("DAMN ! worker %d (pid: %d) died :( trying respawn ...\n", uwsgi.mywid, (int) diedpid);
			}
		}
		// manage_next_request is zero, but killed by signal...
		else if (WIFSIGNALED(waitpid_status)) {
			uwsgi_log("DAMN ! worker %d (pid: %d) MISTERIOUSLY killed by signal %d :( trying respawn ...\n", uwsgi.mywid, (int) diedpid, (int) WTERMSIG(waitpid_status));
		}

		if (uwsgi.workers[uwsgi.mywid].cheaped == 1) {
			uwsgi.workers[uwsgi.mywid].pid = 0;
			uwsgi_log("uWSGI worker %d cheaped.\n", uwsgi.mywid);
			uwsgi.workers[uwsgi.mywid].harakiri = 0;
			continue;
		}
		gettimeofday(&last_respawn, NULL);
		if (last_respawn.tv_sec <= uwsgi.respawn_delta + check_interval) {
			last_respawn_rate++;
			if (last_respawn_rate > uwsgi.numproc) {
				if (uwsgi.forkbomb_delay > 0) {
					uwsgi_log("worker respawning too fast !!! i have to sleep a bit (%d seconds)...\n", uwsgi.forkbomb_delay);
					/* use --forkbomb-delay 0 to disable sleeping */
					sleep(uwsgi.forkbomb_delay);
				}
				last_respawn_rate = 0;
			}
		}
		else {
			last_respawn_rate = 0;
		}
		gettimeofday(&last_respawn, NULL);
		uwsgi.respawn_delta = last_respawn.tv_sec;

		if (uwsgi_respawn_worker(uwsgi.mywid))
			return 0;

		// end of the loop
	}

	// never here
}
Beispiel #26
0
int
main (int argc, char *argv[])
{
  int var = 1;

  /* The fork system call is used by a process to request
     that the kernel create a new process.

     After fork has been called a new child process exists.
     Both the parent and the child then keep executing
     from the point right after the call to fork.
     Thus, both the parent and the child process both
     get a return value from fork.

     The child process gets a return value of 0, and
     the parent process gets a return value equal to the
     process ID of the newly created child.
   */
  int c1 = 0;
  c1 = fork ();
  if (c1 == 0)
    {

      /* we enter this block only if fork returns 0,
         which indicates that we are the child process */
      printf ("Value of var from child = %d\n", var);
      ++var;			// var is only incremented in the child process
    }
  else
    {

      // the parent process does not increment var; it sleeps instead
      int status;
      int retvalue = 0;
      while (retvalue != c1)

	{
	  status = 0;
	  retvalue = waitpid (c1, &status, 0);
	  if (retvalue < 0)

	    {
	      char buffer[256];
	      strerror_r (errno, buffer, 256);
	      printf ("error occured %s\n", buffer);
	      break;
	    }

	  else

	    {
	      printf ("state of process %d changed - ", retvalue);
	      if (WIFEXITED (status))
		{
		  printf ("exited, status=%d\n", WEXITSTATUS (status));
		}
	      else if (WIFSIGNALED (status))
		{
		  printf ("killed by signal %d\n", WTERMSIG (status));
		}
	      else if (WIFSTOPPED (status))
		{
		  printf ("stopped by signal %d\n", WSTOPSIG (status));
		}
	      else if (WIFCONTINUED (status))
		{
		  printf ("continued\n");
		}
	    }
	}
    }

  /* The line below will be executed twice: once from the
     child and once from the parent.

     Recall that the parent process and child process have
     separate address spaces; thus, because only the child
     incremented the value of var, only the child will
     print that the value of var is 2.
   */
  printf ("From process %d, value of var is %d.\n", getpid (), var);
  return 0;
}
Beispiel #27
0
Datei: helper.c Projekt: 1587/ltp
int main(int argc, char *argv[])
{
	int ret;
	pthread_t th;
	pid_t chk;
	int status;
	char *ts = "[??:??:??]";
	struct tm *now;
	time_t nw;

	/* check args */
	if (argc < 3) {
		printf("\nUsage: \n");
		printf("  $ %s n exe arglist\n", argv[0]);
		printf("\nWhere:\n");
		printf("  n       is the timeout duration in hours,\n");
		printf("  exe     is the stress test executable to monitor,\n");
		printf
		    ("  arglist is the arguments to be passed to executable.\n\n");
		return 2;
	}

	timeout = atoi(argv[1]);
	if (timeout < 1) {
		fprintf(stderr,
			"Invalid timeout value \"%s\". Timeout must be a positive integer.\n",
			argv[1]);
		return 2;
	}

	/* create the timer thread */
	ret = pthread_create(&th, NULL, timer, NULL);
	if (ret != 0) {
		perror("Failed to create the timeout thread\n");
		return 2;
	}

	/* Create the new process for the stress test */
	child = fork();

	if (child == (pid_t) - 1) {
		perror("Failed to create a new process");
		exit(2);
	}

	/* The child process executes the test */
	if (child == (pid_t) 0) {

		/* Execute the command */
		ret = execvp(argv[2], &argv[2]);
		if (ret == -1) {
			/* Application was not launched */
			perror("Unable to run child application");
			return 2;
		}
		assert(0);
		perror("Should not see me");
		return 2;
	}

	/* The parent: */

	/* wait for the child process to terminate */
	chk = waitpid(child, &status, 0);
	if (chk != child) {
		perror("Got the wrong process image status");
		return 2;
	}

	/* Cancel the timer thread in case the process returned by itself */
	(void)pthread_cancel(th);

	ret = pthread_join(th, NULL);
	if (ret != 0) {
		perror("Unable to join the timer thread");
		return 2;
	}

	/* return */
	nw = time(NULL);
	now = localtime(&nw);
	if (now == NULL)
		printf(ts);
	else
		printf("[%2.2d:%2.2d:%2.2d]", now->tm_hour, now->tm_min,
		       now->tm_sec);
	if (!WIFEXITED(status)) {
		printf("The stress sample did not exit\n");
		if (WIFSIGNALED(status)) {
			printf("It was killed with signal %i\n",
			       WTERMSIG(status));
		} else {
			printf("and it was not killed...\n");
		}
		exit(1);
	}
	if (WEXITSTATUS(status) == 0) {
		printf("Test %s PASSED\n", argv[2]);
	} else {
		printf("Test %s: returned %d\n", argv[2], WEXITSTATUS(status));
	}
	exit(WEXITSTATUS(status));
}
Beispiel #28
0
static void
process_children(void)
{
    int			i;		/* Looping var */
    int			status;		/* Exit status of child */
    int			pid;		/* Process ID of child */
    cupsd_backend_t	*backend;	/* Current backend */
    const char		*name;		/* Name of process */


    /*
     * Reset the dead_children flag...
     */

    dead_children = 0;

    /*
     * Collect the exit status of some children...
     */

#ifdef HAVE_WAITPID
    while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
#elif defined(HAVE_WAIT3)
    while ((pid = wait3(&status, WNOHANG, NULL)) > 0)
#else
    if ((pid = wait(&status)) > 0)
#endif /* HAVE_WAITPID */
    {
        if (status == SIGTERM)
            status = 0;

        for (i = num_backends, backend = backends; i > 0; i --, backend ++)
            if (backend->pid == pid)
                break;

        if (i > 0)
        {
            name            = backend->name;
            backend->pid    = 0;
            backend->status = status;

            active_backends --;
        }
        else
            name = "Unknown";

        if (status)
        {
            if (WIFEXITED(status))
                fprintf(stderr,
                        "ERROR: [cups-deviced] PID %d (%s) stopped with status %d!\n",
                        pid, name, WEXITSTATUS(status));
            else
                fprintf(stderr,
                        "ERROR: [cups-deviced] PID %d (%s) crashed on signal %d!\n",
                        pid, name, WTERMSIG(status));
        }
        else
            fprintf(stderr,
                    "DEBUG: [cups-deviced] PID %d (%s) exited with no errors.\n",
                    pid, name);
    }
}
Beispiel #29
0
/*
 *  Collect the child's exit status. The initiating thread must do this on uClibc. 
 *  Return zero if the exit status is successfully reaped. Return -1 if an error 
 *  and return > 0 if process still running.
 */
int mprReapCmd(MprCmd *cmd, int timeout)
{
    MprTime     mark;

    mprAssert(cmd->pid);

    if (timeout < 0) {
        timeout = MAXINT;
    }
    mark = mprGetTime(cmd);

    while (cmd->pid) {
#if BLD_UNIX_LIKE
        int     status, waitrc;
        status = 0;
        if ((waitrc = waitpid(cmd->pid, &status, WNOHANG | __WALL)) < 0) {
            mprAssert(0);
            mprLog(cmd, 0, "waitpid failed for pid %d, errno %d", cmd->pid, errno);
            return MPR_ERR_CANT_READ;

        } else if (waitrc == cmd->pid) {
            if (!WIFSTOPPED(status)) {
                if (WIFEXITED(status)) {
                    cmd->status = WEXITSTATUS(status);
                } else if (WIFSIGNALED(status)) {
                    cmd->status = WTERMSIG(status);
                }
                cmd->pid = 0;
            }
            break;
            
        } else {
            mprAssert(waitrc == 0);
        }
#endif
#if VXWORKS
        /*
         *  The command exit status (cmd->status) is set in cmdTaskEntry
         */
        if (semTake(cmd->exitCond, MPR_TIMEOUT_STOP_TASK) != OK) {
            mprError(cmd, "cmd: child %s did not exit, errno %d", cmd->program);
            return MPR_ERR_CANT_CREATE;
        }
        semDelete(cmd->exitCond);
        cmd->exitCond = 0;
        cmd->pid = 0;
#endif
#if BLD_WIN_LIKE
        int     status, rc;
        if ((rc = WaitForSingleObject(cmd->process, 10)) != WAIT_OBJECT_0) {
            if (rc == WAIT_TIMEOUT) {
                return -MPR_ERR_TIMEOUT;
            }
            mprLog(cmd, 6, "cmd: WaitForSingleObject no child to reap rc %d, %d", rc, GetLastError());
            return MPR_ERR_CANT_READ;
        }
        if (GetExitCodeProcess(cmd->process, (ulong*) &status) == 0) {
            mprLog(cmd, 7, "cmd: GetExitProcess error");
            return MPR_ERR_CANT_READ;
        }
        if (status != STILL_ACTIVE) {
            cmd->status = status;
            CloseHandle(cmd->process);
            CloseHandle(cmd->thread);
            cmd->process = 0;
            cmd->pid = 0;
            break;
        }
#endif
        if (mprGetElapsedTime(cmd, mark) > timeout) {
            break;
        }
        /* Prevent busy waiting */
        mprSleep(cmd, 10);
    }
    return (cmd->pid == 0) ? 0 : 1;
}
Beispiel #30
0
static int openInputDevice(lua_State *L) {
	const char* inputdevice = luaL_checkstring(L, 1);
#ifndef EMULATE_READER
	int fd;
	int childpid;
	fd = findFreeFdSlot();
	if(fd == -1) {
		return luaL_error(L, "no free slot for new input device <%s>", inputdevice);
	}
	if(!strcmp("fake_events", inputdevice)) {
		/* special case: the power slider */
		int pipefd[2];

		pipe(pipefd);
		if((childpid = fork()) == -1) {
			return luaL_error(L, "cannot fork() slider event listener");
		}
		if(childpid == 0) {
			// We send a SIGTERM to this child on exit, trap it to kill lipc properly.
			signal(SIGTERM, slider_handler);

			FILE *fp;
			char std_out[256];
			int status;
			struct input_event ev;
			__u16 key_code = 10000;

			close(pipefd[0]);

			ev.type = EV_KEY;
			ev.code = key_code;
			ev.value = 1;

			/* listen power slider events (listen for ever for multiple events) */
			char *argv[] = {"lipc-wait-event", "-m", "-s", "0", "com.lab126.powerd", "goingToScreenSaver,outOfScreenSaver,charging,notCharging", (char *) NULL};
			/* @TODO  07.06 2012 (houqp)
			*  plugin and out event can only be watched by:
				lipc-wait-event com.lab126.hal usbPlugOut,usbPlugIn
			*/

			fp = popen_noshell("lipc-wait-event", (const char * const *)argv, "r", &pclose_arg, 0);
			if (!fp) {
				err(EXIT_FAILURE, "popen_noshell()");
			}

			/* Flush to get rid of buffering issues? */
			fflush(fp);

			while(fgets(std_out, sizeof(std_out)-1, fp)) {
				if(std_out[0] == 'g') {
					ev.code = CODE_IN_SAVER;
				} else if(std_out[0] == 'o') {
					ev.code = CODE_OUT_SAVER;
				} else if((std_out[0] == 'u') && (std_out[7] == 'I')) {
					ev.code = CODE_USB_PLUG_IN;
				} else if((std_out[0] == 'u') && (std_out[7] == 'O')) {
					ev.code = CODE_USB_PLUG_OUT;
				} else if(std_out[0] == 'c') {
					ev.code = CODE_CHARGING;
				} else if(std_out[0] == 'n') {
					ev.code = CODE_NOT_CHARGING;
				} else {
					printf("Unrecognized event.\n");
				}
				/* fill event struct */
				gettimeofday(&ev.time, NULL);

				/* generate event */
				if(write(pipefd[1], &ev, sizeof(struct input_event)) == -1) {
					printf("Failed to generate event.\n");
				}
			}

			status = pclose_noshell(&pclose_arg);
			if (status == -1) {
				err(EXIT_FAILURE, "pclose_noshell()");
			} else {
				if (WIFEXITED(status)) {
					printf("lipc-wait-event exited normally with status: %d\n", WEXITSTATUS(status));
				} else if (WIFSIGNALED(status)) {
					printf("lipc-wait-event was killed by signal %d\n", WTERMSIG(status));
				} else if (WIFSTOPPED(status)) {
					printf("lipc-wait-event was stopped by signal %d\n", WSTOPSIG(status));
				} else if (WIFCONTINUED(status)) {
					printf("lipc-wait-event continued\n");
				}
			}

			// We're done, go away :).
			_exit(EXIT_SUCCESS);
		} else {
			close(pipefd[1]);
			inputfds[fd] = pipefd[0];
			slider_pid = childpid;
		}
	} else {
		inputfds[fd] = open(inputdevice, O_RDONLY | O_NONBLOCK, 0);
		if(inputfds[fd] != -1) {
			ioctl(inputfds[fd], EVIOCGRAB, 1);
			return 0;
		} else {
			return luaL_error(L, "error opening input device <%s>: %d", inputdevice, errno);
		}
	}
#else
	if(SDL_Init(SDL_INIT_VIDEO) < 0) {
		return luaL_error(L, "cannot initialize SDL.");
	}
	SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
	/* we only use inputfds[0] in emu mode, because we only have one
	 * fake device so far. */
	inputfds[0] = open(inputdevice, O_RDWR | O_NONBLOCK);
	if (inputfds < 0) {
		return luaL_error(L, "error opening input device <%s>: %d", inputdevice, errno);
	}
#endif
	return 0;
}