// XXX: update when JVMP_ShmRequest changed static int JVMP_MarshallShmReq(JVMP_ShmRequest* req, char* *res, int *plen) { #define ADD_VAL(val) \ size = sizeof(val); \ if (pos+size >= len) { len = pos+size+step; buf = realloc(buf, len); } \ memcpy(buf+pos, &val, size); \ pos += size; argc++; #define ADD_REF(ref, size) \ if (pos+size >= len) { len = pos+size+step; buf = realloc(buf, len); } \ memcpy(buf+pos, ref, size); \ pos += size; argc++; int len=0, pos=0, size, step=20, argc=0; char* buf = NULL; if (!req) return 0; ADD_VAL(req->rid); ADD_VAL(req->msg_id); ADD_VAL(req->func_no); ADD_VAL(req->retval); ADD_VAL(req->argc); ADD_REF(req->argt, strlen(req->argt)+1); ADD_VAL(req->nullmask); ADD_VAL(req->length); ADD_REF(req->data, req->length); ADD_VAL(req->shmlen); ADD_VAL(req->shmid); ADD_VAL(req->caps); // there's no ADD_REF(req->shmdata, req->length); as it's SHARED *res = buf; *plen = pos; return 1; }
int rpmsqEnable(int signum, rpmsqAction_t handler) { int tblsignum = (signum >= 0 ? signum : -signum); struct sigaction sa; rpmsig tbl; int ret = -1; for (tbl = rpmsigTbl; tbl->signum >= 0; tbl++) { if (tblsignum != tbl->signum) continue; if (signum >= 0) { /* Enable. */ if (ADD_REF(tbl) <= 0) { (void) sigdelset(&rpmsqCaught, tbl->signum); /* XXX Don't set a signal handler if already SIG_IGN */ (void) sigaction(tbl->signum, NULL, &tbl->oact); if (tbl->oact.sa_handler == SIG_IGN) continue; (void) sigemptyset (&sa.sa_mask); #ifdef SA_SIGINFO sa.sa_flags = SA_SIGINFO; #else sa.sa_flags = 0; #endif sa.sa_sigaction = (handler != NULL ? handler : tbl->handler); if (sigaction(tbl->signum, &sa, &tbl->oact) < 0) { SUB_REF(tbl); break; } tbl->active = 1; /* XXX just in case */ if (handler != NULL) tbl->handler = handler; } } else { /* Disable. */ if (SUB_REF(tbl) <= 0) { if (sigaction(tbl->signum, &tbl->oact, NULL) < 0) break; tbl->active = 0; /* XXX just in case */ tbl->handler = (handler != NULL ? handler : rpmsqAction); } } ret = tbl->active; break; } return ret; }
/* Execute LINE as a shell command, returning its status. */ static int do_system (const char *line) { int status, save; pid_t pid; struct sigaction sa; #ifndef _LIBC_REENTRANT struct sigaction intr, quit; #endif sigset_t omask; sa.sa_handler = SIG_IGN; sa.sa_flags = 0; __sigemptyset (&sa.sa_mask); DO_LOCK (); if (ADD_REF () == 0) { if (__sigaction (SIGINT, &sa, &intr) < 0) { (void) SUB_REF (); goto out; } if (__sigaction (SIGQUIT, &sa, &quit) < 0) { save = errno; (void) SUB_REF (); goto out_restore_sigint; } } DO_UNLOCK (); /* We reuse the bitmap in the 'sa' structure. */ __sigaddset (&sa.sa_mask, SIGCHLD); save = errno; if (__sigprocmask (SIG_BLOCK, &sa.sa_mask, &omask) < 0) { #ifndef _LIBC if (errno == ENOSYS) __set_errno (save); else #endif { DO_LOCK (); if (SUB_REF () == 0) { save = errno; (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL); out_restore_sigint: (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL); __set_errno (save); } out: DO_UNLOCK (); return -1; } } #ifdef CLEANUP_HANDLER CLEANUP_HANDLER; #endif #ifdef FORK pid = FORK (); #else pid = __fork (); #endif if (pid == (pid_t) 0) { /* Child side. */ const char *new_argv[4]; new_argv[0] = SHELL_NAME; new_argv[1] = "-c"; new_argv[2] = line; new_argv[3] = NULL; /* Restore the signals. */ (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL); (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL); (void) __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL); INIT_LOCK (); /* Exec the shell. */ (void) __execve (SHELL_PATH, (char *const *) new_argv, __environ); _exit (127); } else if (pid < (pid_t) 0) /* The fork failed. */ status = -1; else /* Parent side. */ { /* Note the system() is a cancellation point. But since we call waitpid() which itself is a cancellation point we do not have to do anything here. */ if (TEMP_FAILURE_RETRY (__waitpid (pid, &status, 0)) != pid) status = -1; } #ifdef CLEANUP_HANDLER CLEANUP_RESET; #endif save = errno; DO_LOCK (); if ((SUB_REF () == 0 && (__sigaction (SIGINT, &intr, (struct sigaction *) NULL) | __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL)) != 0) || __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL) != 0) { #ifndef _LIBC /* glibc cannot be used on systems without waitpid. */ if (errno == ENOSYS) __set_errno (save); else #endif status = -1; } DO_UNLOCK (); return status; }
/* Execute LINE as a shell command, returning its status. */ static int do_system (const char *line) { int status, save; pid_t pid; struct sigaction sa; sigset_t omask; memset(&sa, 0, sizeof(sa)); sa.sa_handler = SIG_IGN; /*sa.sa_flags = 0; - done by memset */ /*__sigemptyset (&sa.sa_mask); - done by memset */ DO_LOCK (); if (ADD_REF () == 0) { if (sigaction (SIGINT, &sa, &intr) < 0) { SUB_REF (); goto out; } if (sigaction (SIGQUIT, &sa, &quit) < 0) { save = errno; SUB_REF (); goto out_restore_sigint; } } DO_UNLOCK (); /* We reuse the bitmap in the 'sa' structure. */ __sigaddset (&sa.sa_mask, SIGCHLD); save = errno; if (sigprocmask (SIG_BLOCK, &sa.sa_mask, &omask) < 0) { { DO_LOCK (); if (SUB_REF () == 0) { save = errno; (void) sigaction (SIGQUIT, &quit, (struct sigaction *) NULL); out_restore_sigint: (void) sigaction (SIGINT, &intr, (struct sigaction *) NULL); __set_errno (save); } out: DO_UNLOCK (); return -1; } } CLEANUP_HANDLER; pid = FORK (); if (pid == (pid_t) 0) { /* Child side. */ const char *new_argv[4]; new_argv[0] = "/bin/sh"; new_argv[1] = "-c"; new_argv[2] = line; new_argv[3] = NULL; /* Restore the signals. */ (void) sigaction (SIGINT, &intr, (struct sigaction *) NULL); (void) sigaction (SIGQUIT, &quit, (struct sigaction *) NULL); (void) sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL); INIT_LOCK (); /* Exec the shell. */ (void) execve ("/bin/sh", (char *const *) new_argv, __environ); _exit (127); } else if (pid < (pid_t) 0) /* The fork failed. */ status = -1; else /* Parent side. */ { /* Note the system() is a cancellation point. But since we call waitpid() which itself is a cancellation point we do not have to do anything here. */ if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid) status = -1; } CLEANUP_RESET; save = errno; DO_LOCK (); if ((SUB_REF () == 0 && (sigaction (SIGINT, &intr, (struct sigaction *) NULL) | sigaction (SIGQUIT, &quit, (struct sigaction *) NULL)) != 0) || sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL) != 0) { status = -1; } DO_UNLOCK (); return status; }