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); } }
pid_t regress_fork(void) { pid_t pid = fork(); #ifdef FORK_BREAKS_GCOV vproc_transaction_begin(0); #endif return pid; }
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]); } }
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 }
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__ */ }
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); }
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); }