예제 #1
0
void safe_vproc_transaction_begin(void)
	{
	if (vproc_transaction_begin)
		{
		if (transaction) { LogMsg("safe_vproc_transaction_begin: Already have a transaction"); }
		else transaction = vproc_transaction_begin(NULL);
		}
	}
예제 #2
0
pid_t
regress_fork(void)
{
	pid_t pid = fork();
#ifdef FORK_BREAKS_GCOV
	vproc_transaction_begin(0);
#endif
	return pid;
}
예제 #3
0
파일: sysman.c 프로젝트: ystk/debian-cups
void
cupsdSetBusyState(void)
{
  int		newbusy;		/* New busy state */
  static int	busy = 0;		/* Current busy state */
  static const char * const busy_text[] =
  {					/* Text for busy states */
    "Not busy",
    "Dirty files",
    "Printing jobs",
    "Printing jobs and dirty files",
    "Active clients",
    "Active clients and dirty files",
    "Active clients and printing jobs",
    "Active clients, printing jobs, and dirty files"
  };
#ifdef HAVE_VPROC_TRANSACTION_BEGIN
  static vproc_transaction_t vtran = 0;	/* Current busy transaction */
#endif /* HAVE_VPROC_TRANSACTION_BEGIN */


  newbusy = (DirtyCleanTime ? 1 : 0) |
            (cupsArrayCount(PrintingJobs) ? 2 : 0) |
	    (cupsArrayCount(ActiveClients) ? 4 : 0);

  if (newbusy != busy)
  {
    busy = newbusy;

#ifdef HAVE_VPROC_TRANSACTION_BEGIN
    if (busy && !vtran)
      vtran = vproc_transaction_begin(NULL);
    else if (!busy && vtran)
    {
      vproc_transaction_end(NULL, vtran);
      vtran = 0;
    }
#endif /* HAVE_VPROC_TRANSACTION_BEGIN */

    cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdSetBusyState: %s", busy_text[busy]);
  }
}
예제 #4
0
static enum outcome
testcase_run_forked_(const struct testgroup_t *group,
		     const struct testcase_t *testcase)
{
#ifdef _WIN32
	/* Fork? On Win32?  How primitive!  We'll do what the smart kids do:
	   we'll invoke our own exe (whose name we recall from the command
	   line) with a command line that tells it to run just the test we
	   want, and this time without forking.

	   (No, threads aren't an option.  The whole point of forking is to
	   share no state between tests.)
	 */
	int ok;
	char buffer[LONGEST_TEST_NAME+256];
	STARTUPINFOA si;
	PROCESS_INFORMATION info;
	DWORD exitcode;

	if (!in_tinytest_main) {
		printf("\nERROR.  On Windows, testcase_run_forked_ must be"
		       " called from within tinytest_main.\n");
		abort();
	}
	if (opt_verbosity>0)
		printf("[forking] ");

	snprintf(buffer, sizeof(buffer), "%s --RUNNING-FORKED %s %s%s",
		 commandname, verbosity_flag, group->prefix, testcase->name);

	memset(&si, 0, sizeof(si));
	memset(&info, 0, sizeof(info));
	si.cb = sizeof(si);

	ok = CreateProcessA(commandname, buffer, NULL, NULL, 0,
			   0, NULL, NULL, &si, &info);
	if (!ok) {
		printf("CreateProcess failed!\n");
		return 0;
	}
	WaitForSingleObject(info.hProcess, INFINITE);
	GetExitCodeProcess(info.hProcess, &exitcode);
	CloseHandle(info.hProcess);
	CloseHandle(info.hThread);
	if (exitcode == 0)
		return OK;
	else if (exitcode == MAGIC_EXITCODE)
		return SKIP;
	else
		return FAIL;
#else
	int outcome_pipe[2];
	pid_t pid;
	(void)group;

	if (pipe(outcome_pipe))
		perror("opening pipe");

	if (opt_verbosity>0)
		printf("[forking] ");
	pid = fork();
#ifdef FORK_BREAKS_GCOV
	vproc_transaction_begin(0);
#endif
	if (!pid) {
		/* child. */
		int test_r, write_r;
		char b[1];
		close(outcome_pipe[0]);
		test_r = testcase_run_bare_(testcase);
		assert(0<=(int)test_r && (int)test_r<=2);
		b[0] = "NYS"[test_r];
		write_r = (int)write(outcome_pipe[1], b, 1);
		if (write_r != 1) {
			perror("write outcome to pipe");
			exit(1);
		}
		exit(0);
		return FAIL; /* unreachable */
	} else {
		/* parent */
		int status, r;
		char b[1];
		/* Close this now, so that if the other side closes it,
		 * our read fails. */
		close(outcome_pipe[1]);
		r = (int)read(outcome_pipe[0], b, 1);
		if (r == 0) {
			printf("[Lost connection!] ");
			return 0;
		} else if (r != 1) {
			perror("read outcome from pipe");
		}
		waitpid(pid, &status, 0);
		close(outcome_pipe[0]);
		return b[0]=='Y' ? OK : (b[0]=='S' ? SKIP : FAIL);
	}
#endif
}
예제 #5
0
파일: sysman.c 프로젝트: AndychenCL/cups
void
cupsdSetBusyState(void)
{
  int			i;		/* Looping var */
  cupsd_job_t		*job;		/* Current job */
  cupsd_printer_t	*p;		/* Current printer */
  int			newbusy;	/* New busy state */
  static int		busy = 0;	/* Current busy state */
  static const char * const busy_text[] =
  {					/* Text for busy states */
    "Not busy",
    "Dirty files",
    "Printing jobs",
    "Printing jobs and dirty files",
    "Active clients",
    "Active clients and dirty files",
    "Active clients and printing jobs",
    "Active clients, printing jobs, and dirty files"
  };
#ifdef __APPLE__
  static vproc_transaction_t vtran = 0;	/* Current busy transaction */
  static IOPMAssertionID keep_awake = 0;/* Keep the system awake while printing */
#endif /* __APPLE__ */


 /*
  * Figure out how busy we are...
  */

  newbusy = (DirtyCleanTime ? 1 : 0) |
	    (cupsArrayCount(ActiveClients) ? 4 : 0);

  for (job = (cupsd_job_t *)cupsArrayFirst(PrintingJobs);
       job;
       job = (cupsd_job_t *)cupsArrayNext(PrintingJobs))
  {
    if ((p = job->printer) != NULL)
    {
      for (i = 0; i < p->num_reasons; i ++)
	if (!strcmp(p->reasons[i], "connecting-to-device"))
	  break;

      if (!p->num_reasons || i >= p->num_reasons)
	break;
    }
  }

  if (job)
    newbusy |= 2;

  cupsdLogMessage(CUPSD_LOG_DEBUG,
                  "cupsdSetBusyState: newbusy=\"%s\", busy=\"%s\"",
                  busy_text[newbusy], busy_text[busy]);

 /*
  * Manage state changes...
  */

  if (newbusy != busy)
  {
    busy = newbusy;

#ifdef __APPLE__
    if (busy && !vtran)
      vtran = vproc_transaction_begin(NULL);
    else if (!busy && vtran)
    {
      vproc_transaction_end(NULL, vtran);
      vtran = 0;
    }
#endif /* __APPLE__ */
  }

#ifdef __APPLE__
  if (cupsArrayCount(PrintingJobs) > 0 && !keep_awake)
  {
    cupsdLogMessage(CUPSD_LOG_DEBUG, "Asserting NetworkClientActive.");

    IOPMAssertionCreateWithName(kIOPMAssertNetworkClientActive,
				kIOPMAssertionLevelOn,
				CFSTR("org.cups.cupsd"), &keep_awake);
  }
  else if (cupsArrayCount(PrintingJobs) == 0 && keep_awake)
  {
    cupsdLogMessage(CUPSD_LOG_DEBUG, "Releasing power assertion.");
    IOPMAssertionRelease(keep_awake);
    keep_awake = 0;
  }
#endif /* __APPLE__ */
}
예제 #6
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line arguments */
     char *argv[])			/* I - Command-line arguments */
{
  int		i;			/* Looping var */
  int		num_defaults;		/* Number of default options */
  cups_option_t	*defaults;		/* Default options */
  char		line[256],		/* Command string */
		command,		/* Command code */
		*dest,			/* Pointer to destination */
		*list,			/* Pointer to list */
		*agent,			/* Pointer to user */
		status;			/* Status for client */
  socklen_t	hostlen;		/* Size of client address */
  http_addr_t	hostaddr;		/* Address of client */
  char		hostname[256],		/* Name of client */
		hostip[256],		/* IP address */
		*hostfamily;		/* Address family */
  int		hostlookups;		/* Do hostname lookups? */
#ifdef __APPLE__
  vproc_transaction_t vtran = vproc_transaction_begin(NULL);
#endif /* __APPLE__ */


 /*
  * Don't buffer the output...
  */

  setbuf(stdout, NULL);

 /*
  * Log things using the "cups-lpd" name...
  */

  openlog("cups-lpd", LOG_PID, LOG_LPR);

 /*
  * Scan the command-line for options...
  */

  num_defaults = 0;
  defaults     = NULL;
  hostlookups  = 1;

  for (i = 1; i < argc; i ++)
    if (argv[i][0] == '-')
    {
      switch (argv[i][1])
      {
        case 'h' : /* -h hostname[:port] */
            if (argv[i][2])
	      cupsSetServer(argv[i] + 2);
	    else
	    {
	      i ++;
	      if (i < argc)
	        cupsSetServer(argv[i]);
	      else
	        syslog(LOG_WARNING, "Expected hostname string after -h option!");
	    }
	    break;

	case 'o' : /* Option */
	    if (argv[i][2])
	      num_defaults = cupsParseOptions(argv[i] + 2, num_defaults,
	                                      &defaults);
	    else
	    {
	      i ++;
	      if (i < argc)
		num_defaults = cupsParseOptions(argv[i], num_defaults,
		                                &defaults);
              else
        	syslog(LOG_WARNING, "Expected option string after -o option!");
            }
	    break;

        case 'n' : /* Don't do hostname lookups */
	    hostlookups = 0;
	    break;

	default :
	    syslog(LOG_WARNING, "Unknown option \"%c\" ignored!", argv[i][1]);
	    break;
      }
    }
    else
      syslog(LOG_WARNING, "Unknown command-line option \"%s\" ignored!",
             argv[i]);

 /*
  * Get the address of the client...
  */

  hostlen = sizeof(hostaddr);

  if (getpeername(0, (struct sockaddr *)&hostaddr, &hostlen))
  {
    syslog(LOG_WARNING, "Unable to get client address - %s", strerror(errno));
    strlcpy(hostname, "unknown", sizeof(hostname));
  }
  else
  {
    httpAddrString(&hostaddr, hostip, sizeof(hostip));

    if (hostlookups)
      httpAddrLookup(&hostaddr, hostname, sizeof(hostname));
    else
      strlcpy(hostname, hostip, sizeof(hostname));

#ifdef AF_INET6
    if (hostaddr.addr.sa_family == AF_INET6)
      hostfamily = "IPv6";
    else
#endif /* AF_INET6 */
    hostfamily = "IPv4";

    syslog(LOG_INFO, "Connection from %s (%s %s)", hostname, hostfamily,
           hostip);
  }

  num_defaults = cupsAddOption("job-originating-host-name", hostname,
                               num_defaults, &defaults);

 /*
  * RFC1179 specifies that only 1 daemon command can be received for
  * every connection.
  */

  if (smart_gets(line, sizeof(line), stdin) == NULL)
  {
   /*
    * Unable to get command from client!  Send an error status and return.
    */

    syslog(LOG_ERR, "Unable to get command line from client!");
    putchar(1);

#ifdef __APPLE__
    vproc_transaction_end(NULL, vtran);
#endif /* __APPLE__ */

    return (1);
  }

 /*
  * The first byte is the command byte.  After that will be the queue name,
  * resource list, and/or user name.
  */

  if ((command = line[0]) == '\0')
    dest = line;
  else
    dest = line + 1;

  if (command == 0x02)
    list = NULL;
  else
  {
    for (list = dest; *list && !isspace(*list & 255); list ++);

    while (isspace(*list & 255))
      *list++ = '\0';
  }

 /*
  * Do the command...
  */

  switch (command)
  {
    default : /* Unknown command */
        syslog(LOG_ERR, "Unknown LPD command 0x%02X!", command);
        syslog(LOG_ERR, "Command line = %s", line + 1);
	putchar(1);

        status = 1;
	break;

    case 0x01 : /* Print any waiting jobs */
        syslog(LOG_INFO, "Print waiting jobs (no-op)");
	putchar(0);

        status = 0;
	break;

    case 0x02 : /* Receive a printer job */
        syslog(LOG_INFO, "Receive print job for %s", dest);
        /* recv_print_job() sends initial status byte */

        status = (char)recv_print_job(dest, num_defaults, defaults);
	break;

    case 0x03 : /* Send queue state (short) */
        syslog(LOG_INFO, "Send queue state (short) for %s %s", dest, list);
	/* no status byte for this command */

        status = (char)send_state(dest, list, 0);
	break;

    case 0x04 : /* Send queue state (long) */
        syslog(LOG_INFO, "Send queue state (long) for %s %s", dest, list);
	/* no status byte for this command */

        status = (char)send_state(dest, list, 1);
	break;

    case 0x05 : /* Remove jobs */
        if (list)
	{
	 /*
	  * Grab the agent and skip to the list of users and/or jobs.
	  */

	  agent = list;

	  for (; *list && !isspace(*list & 255); list ++);
	  while (isspace(*list & 255))
	    *list++ = '\0';

	  syslog(LOG_INFO, "Remove jobs %s on %s by %s", list, dest, agent);

	  status = (char)remove_jobs(dest, agent, list);
        }
	else
	  status = 1;

	putchar(status);
	break;
  }

  syslog(LOG_INFO, "Closing connection");
  closelog();

#ifdef __APPLE__
  vproc_transaction_end(NULL, vtran);
#endif /* __APPLE__ */

  return (status);
}
예제 #7
0
int
main(int argc, char *argv[])
{
    register char **sptr = server;
    register char **cptr = client;
    register char **ptr;
    int pid;
    int client_given = 0, server_given = 0;
    int client_args_given = 0, server_args_given = 0;
    int start_of_client_args, start_of_server_args;
    struct sigaction sa, si;
#ifdef __APPLE__
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
    vproc_transaction_t vt;
#endif
#endif

    program = *argv++;
    argc--;
    /*
     * copy the client args.
     */
    if (argc == 0 ||
        (**argv != '/' && **argv != '.')) {
        for (ptr = default_client; *ptr; )
            *cptr++ = *ptr++;
    } else {
        client_given = 1;
    }
    start_of_client_args = (cptr - client);
    while (argc && strcmp(*argv, "--")) {
        client_args_given++;
        *cptr++ = *argv++;
        argc--;
    }
    *cptr = NULL;
    if (argc) {
        argv++;
        argc--;
    }

    /*
     * Copy the server args.
     */
    if (argc == 0 ||
        (**argv != '/' && **argv != '.')) {
        *sptr++ = default_server;
    } else {
        server_given = 1;
        *sptr++ = *argv++;
        argc--;
    }
    if (argc > 0 && (argv[0][0] == ':' && isdigit(argv[0][1])))
        displayNum = *argv;
    else
        displayNum = *sptr++ = default_display;

    start_of_server_args = (sptr - server);
    while (--argc >= 0) {
        server_args_given++;
        *sptr++ = *argv++;
    }
    *sptr = NULL;

    /*
     * if no client arguments given, check for a startup file and copy
     * that into the argument list
     */
    if (!client_given) {
        char *cp;
        Bool required = False;

        xinitrcbuf[0] = '\0';
        if ((cp = getenv("XINITRC")) != NULL) {
            snprintf(xinitrcbuf, sizeof(xinitrcbuf), "%s", cp);
            required = True;
        } else if ((cp = getenv("HOME")) != NULL) {
            snprintf(xinitrcbuf, sizeof(xinitrcbuf),
                     "%s/%s", cp, XINITRC);
        }
        if (xinitrcbuf[0]) {
            if (access(xinitrcbuf, F_OK) == 0) {
                client += start_of_client_args - 1;
                client[0] = xinitrcbuf;
            } else if (required) {
                Error("warning, no client init file \"%s\"", xinitrcbuf);
            }
        }
    }

    /*
     * if no server arguments given, check for a startup file and copy
     * that into the argument list
     */
    if (!server_given) {
        char *cp;
        Bool required = False;

        xserverrcbuf[0] = '\0';
        if ((cp = getenv("XSERVERRC")) != NULL) {
            snprintf(xserverrcbuf, sizeof(xserverrcbuf), "%s", cp);
            required = True;
        } else if ((cp = getenv("HOME")) != NULL) {
            snprintf(xserverrcbuf, sizeof(xserverrcbuf),
                     "%s/%s", cp, XSERVERRC);
        }
        if (xserverrcbuf[0]) {
            if (access(xserverrcbuf, F_OK) == 0) {
                server += start_of_server_args - 1;
                server[0] = xserverrcbuf;
            } else if (required) {
                Error("warning, no server init file \"%s\"", xserverrcbuf);
            }
        }
    }

    /*
     * Start the server and client.
     */
    signal(SIGCHLD, SIG_DFL);    /* Insurance */

    /* Let those signal interrupt the wait() call in the main loop */
    memset(&sa, 0, sizeof sa);
    sa.sa_handler = sigCatch;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;    /* do not set SA_RESTART */

    sigaction(SIGTERM, &sa, NULL);
    sigaction(SIGQUIT, &sa, NULL);
    sigaction(SIGINT, &sa, NULL);
    sigaction(SIGHUP, &sa, NULL);
    sigaction(SIGPIPE, &sa, NULL);

    memset(&si, 0, sizeof(si));
    si.sa_handler = sigIgnore;
    sigemptyset(&si.sa_mask);
    si.sa_flags = SA_RESTART;

    sigaction(SIGALRM, &si, NULL);
    sigaction(SIGUSR1, &si, NULL);

#ifdef __APPLE__
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
    vt = vproc_transaction_begin(NULL);
#endif
#endif

    if (startServer(server) > 0
        && startClient(client) > 0) {
        pid = -1;
        while (pid != clientpid && pid != serverpid
               && gotSignal == 0
            )
            pid = wait(NULL);
    }

#ifdef __APPLE__
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
    vproc_transaction_end(NULL, vt);
#endif
#endif

    signal(SIGTERM, SIG_IGN);
    signal(SIGQUIT, SIG_IGN);
    signal(SIGINT, SIG_IGN);
    signal(SIGHUP, SIG_IGN);
    signal(SIGPIPE, SIG_IGN);

    shutdown();

    if (gotSignal != 0) {
        Errorx("unexpected signal %d", gotSignal);
        exit(EXIT_FAILURE);
    }

    if (serverpid < 0)
        Fatalx("server error");
    if (clientpid < 0)
        Fatalx("client error");
    exit(EXIT_SUCCESS);
}
int main(int ac, char *av[])
{
    char *p = NULL;
    kern_return_t kr = KERN_FAILURE;
    long n;
    int ch;
    mach_msg_header_t hdr;

    while ((ch = getopt(ac, av, "dt:")) != -1)
        switch (ch)
        {
        case 'd':
            opt_debug = 1;
            break;
        case 't':
            n = strtol(optarg, &p, 0);
            if ('\0' == optarg[0] || '\0' != *p || n > LONG_MAX || n < 0)
            {
                fprintf(stderr, "Invalid idle timeout: %s\n", optarg);
                exit(EXIT_FAILURE);
            }
            maxidle = n;
            break;
        case '?':
        default:
            fprintf(stderr, "Usage: mDNSResponderHelper [-d] [-t maxidle]\n");
            exit(EXIT_FAILURE);
        }
    ac -= optind;
    av += optind;

    initialize_logging();
    helplog(ASL_LEVEL_INFO, "Starting");
    initialize_id();

#ifndef NO_SECURITYFRAMEWORK
    // We should normally be running as a system daemon.  However, that might not be the case in some scenarios (e.g. debugging).
    // Explicitly ensure that our Keychain operations utilize the system domain.
    if (opt_debug) SecKeychainSetPreferenceDomain(kSecPreferencesDomainSystem);
#endif
    gPort = register_service(kmDNSHelperServiceName);
    if (!gPort)
        exit(EXIT_FAILURE);

    if (maxidle) actualidle = maxidle;

    signal(SIGTERM, handle_sigterm);

    // We use BeginTransactionAtShutdown in the plist that ensures that we will
    // receive a SIGTERM during shutdown rather than a SIGKILL. But launchd (due to some
    // limitation) currently requires us to still start and end the transaction for
    // its proper initialization.
    vproc_transaction_t vt = vproc_transaction_begin(NULL);
    if (vt) vproc_transaction_end(NULL, vt);

    if (initialize_timer()) exit(EXIT_FAILURE);
    for (n=0; n<100000; n++) if (!gRunLoop) usleep(100);
    if (!gRunLoop)
    {
        helplog(ASL_LEVEL_ERR, "gRunLoop not set after waiting");
        exit(EXIT_FAILURE);
    }

    for(;;)
    {
        hdr.msgh_bits = 0;
        hdr.msgh_local_port = gPort;
        hdr.msgh_remote_port = MACH_PORT_NULL;
        hdr.msgh_size = sizeof(hdr);
        hdr.msgh_id = 0;
        kr = mach_msg(&hdr, MACH_RCV_LARGE | MACH_RCV_MSG, 0, hdr.msgh_size, gPort, 0, 0);
        if (MACH_RCV_TOO_LARGE != kr)
            helplog(ASL_LEVEL_ERR, "main MACH_RCV_MSG error: %d %X %s", kr, kr, mach_error_string(kr));

        kr = mach_msg_server_once(helper_server, MAX_MSG_SIZE, gPort,
                                  MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT) | MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0));
        if (KERN_SUCCESS != kr)
        {
            helplog(ASL_LEVEL_ERR, "mach_msg_server: %d %X %s", kr, kr, mach_error_string(kr));
            exit(EXIT_FAILURE);
        }

    }
    exit(EXIT_SUCCESS);
}