00001
00005 #include "system.h"
00006
00007 #if defined(__LCLINT__)
00008 #define _BITS_SIGTHREAD_H
00009
00010
00011
00012
00013 extern int sighold(int sig)
00014 ;
00015 extern int sigignore(int sig)
00016 ;
00017 extern int sigpause(int sig)
00018 ;
00019 extern int sigrelse(int sig)
00020 ;
00021 extern void (*sigset(int sig, void (*disp)(int)))(int)
00022 ;
00023
00024 struct qelem;
00025 extern void __insque(struct qelem * __elem, struct qelem * __prev)
00026 ;
00027 extern void __remque(struct qelem * __elem)
00028 ;
00029
00030 extern pthread_t pthread_self(void)
00031 ;
00032 extern int pthread_equal(pthread_t t1, pthread_t t2)
00033 ;
00034
00035 extern int pthread_create( pthread_t *restrict thread,
00036 const pthread_attr_t *restrict attr,
00037 void *(*start_routine)(void*), void *restrict arg)
00038 ;
00039 extern int pthread_join(pthread_t thread, void **value_ptr)
00040 ;
00041
00042 extern int pthread_setcancelstate(int state, int *oldstate)
00043
00044 ;
00045 extern int pthread_setcanceltype(int type, int *oldtype)
00046
00047 ;
00048 extern void pthread_testcancel(void)
00049
00050 ;
00051 extern void pthread_cleanup_pop(int execute)
00052
00053 ;
00054 extern void pthread_cleanup_push(void (*routine)(void*), void *arg)
00055
00056 ;
00057 extern void _pthread_cleanup_pop( struct _pthread_cleanup_buffer *__buffer, int execute)
00058
00059 ;
00060 extern void _pthread_cleanup_push( struct _pthread_cleanup_buffer *__buffer, void (*routine)(void*), void *arg)
00061
00062 ;
00063
00064 extern int pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
00065
00066 ;
00067 extern int pthread_mutexattr_init( pthread_mutexattr_t *attr)
00068
00069 ;
00070
00071 int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict attr,
00072 int *restrict type)
00073 ;
00074 int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
00075
00076 ;
00077
00078 extern int pthread_mutex_destroy(pthread_mutex_t *mutex)
00079 ;
00080 extern int pthread_mutex_init( pthread_mutex_t *restrict mutex,
00081 const pthread_mutexattr_t *restrict attr)
00082
00083 ;
00084
00085 extern int pthread_mutex_lock(pthread_mutex_t *mutex)
00086
00087 ;
00088 extern int pthread_mutex_trylock(pthread_mutex_t *mutex)
00089
00090 ;
00091 extern int pthread_mutex_unlock(pthread_mutex_t *mutex)
00092
00093 ;
00094
00095 extern int pthread_cond_destroy(pthread_cond_t *cond)
00096 ;
00097 extern int pthread_cond_init( pthread_cond_t *restrict cond,
00098 const pthread_condattr_t *restrict attr)
00099
00100 ;
00101
00102 extern int pthread_cond_timedwait(pthread_cond_t *restrict cond,
00103 pthread_mutex_t *restrict mutex,
00104 const struct timespec *restrict abstime)
00105 ;
00106 extern int pthread_cond_wait(pthread_cond_t *restrict cond,
00107 pthread_mutex_t *restrict mutex)
00108 ;
00109 extern int pthread_cond_broadcast(pthread_cond_t *cond)
00110
00111 ;
00112 extern int pthread_cond_signal(pthread_cond_t *cond)
00113
00114 ;
00115
00116
00117
00118 #endif
00119
00120 #include <signal.h>
00121 #if !defined(__QNX__)
00122 #include <sys/signal.h>
00123 #endif
00124 #include <sys/wait.h>
00125 #include <search.h>
00126
00127
00128 #if !defined(HAVE_SIGHOLD) && defined(HAVE_SIGPROCMASK) && defined(HAVE_SIGADDSET)
00129 static int __RPM_sighold(int sig)
00130 {
00131 sigset_t set;
00132 if (sigprocmask(SIG_SETMASK, NULL, &set) < 0)
00133 return -1;
00134 if (sigaddset(&set, sig) < 0)
00135 return -1;
00136 return sigprocmask(SIG_SETMASK, &set, NULL);
00137 }
00138 #define sighold(sig) __RPM_sighold(sig)
00139 #endif
00140
00141
00142 #if !defined(HAVE_SIGRELSE) && defined(HAVE_SIGPROCMASK) && defined(HAVE_SIGDELSET)
00143 static int __RPM_sigrelse(int sig)
00144 {
00145 sigset_t set;
00146 if (sigprocmask(SIG_SETMASK, NULL, &set) < 0)
00147 return -1;
00148 if (sigdelset(&set, sig) < 0)
00149 return -1;
00150 return sigprocmask(SIG_SETMASK, &set, NULL);
00151 }
00152 #define sigrelse(sig) __RPM_sigrelse(sig)
00153 #endif
00154
00155
00156 #if !defined(HAVE_SIGPAUSE) && defined(HAVE_SIGEMPTYSET) && defined(HAVE_SIGADDSET) && defined(HAVE_SIGSUSPEND)
00157 static int __RPM_sigpause(int sig)
00158 {
00159 sigset_t set;
00160 if (sigemptyset(&set) < 0)
00161 return -1;
00162 if (sigaddset(&set, sig) < 0)
00163 return -1;
00164 return sigsuspend(&set);
00165 }
00166 #define sigpause(sig) __RPM_sigpause(sig)
00167 #endif
00168
00169
00170 #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__QNX__)
00171 struct qelem {
00172 struct qelem *q_forw;
00173 struct qelem *q_back;
00174 };
00175
00176 static void __insque(struct qelem * elem, struct qelem * pred)
00177 {
00178 elem -> q_forw = pred -> q_forw;
00179 pred -> q_forw -> q_back = elem;
00180 elem -> q_back = pred;
00181 pred -> q_forw = elem;
00182 }
00183 #define insque(_e, _p) __insque((_e), (_p))
00184
00185 static void __remque(struct qelem * elem)
00186 {
00187 elem -> q_forw -> q_back = elem -> q_back;
00188 elem -> q_back -> q_forw = elem -> q_forw;
00189 }
00190 #define remque(_e) __remque(_e)
00191 #endif
00192
00193 #if defined(HAVE_PTHREAD_H)
00194
00195 # if !defined(__QNX__)
00196
00197 #if PTHREAD_MUTEX_DEFAULT != PTHREAD_MUTEX_NORMAL
00198 #error RPM expects PTHREAD_MUTEX_DEFAULT == PTHREAD_MUTEX_NORMAL
00199 #endif
00200 # endif
00201
00202 #ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
00203
00204 static pthread_mutex_t rpmsigTbl_lock = PTHREAD_MUTEX_INITIALIZER;
00205 #else
00206
00207
00208 static pthread_mutex_t rpmsigTbl_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
00209
00210 #endif
00211
00212 #define DO_LOCK() pthread_mutex_lock(&rpmsigTbl_lock);
00213 #define DO_UNLOCK() pthread_mutex_unlock(&rpmsigTbl_lock);
00214 #define INIT_LOCK() \
00215 { pthread_mutexattr_t attr; \
00216 (void) pthread_mutexattr_init(&attr); \
00217 (void) pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); \
00218 (void) pthread_mutex_init (&rpmsigTbl_lock, &attr); \
00219 (void) pthread_mutexattr_destroy(&attr); \
00220 rpmsigTbl_sigchld->active = 0; \
00221 }
00222 #define ADD_REF(__tbl) (__tbl)->active++
00223 #define SUB_REF(__tbl) --(__tbl)->active
00224 #define CLEANUP_HANDLER(__handler, __arg, __oldtypeptr) \
00225 (void) pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, (__oldtypeptr));\
00226 pthread_cleanup_push((__handler), (__arg));
00227 #define CLEANUP_RESET(__execute, __oldtype) \
00228 pthread_cleanup_pop(__execute); \
00229 (void) pthread_setcanceltype ((__oldtype), &(__oldtype));
00230
00231 #define SAME_THREAD(_a, _b) pthread_equal(((pthread_t)_a), ((pthread_t)_b))
00232
00233 #define ME() __tid2vp(pthread_self())
00234
00235 static void *__tid2vp(pthread_t tid)
00236
00237 {
00238 union { pthread_t tid; void *vp; } u;
00239 u.tid = tid;
00240 return u.vp;
00241 }
00242
00243 #else
00244
00245 #define DO_LOCK() (0)
00246 #define DO_UNLOCK() (0)
00247 #define INIT_LOCK() ((void)0)
00248 #define ADD_REF(__tbl) (0)
00249 #define SUB_REF(__tbl) (0)
00250 #define CLEANUP_HANDLER(__handler, __arg, __oldtypeptr) ((void)0)
00251 #define CLEANUP_RESET(__execute, __oldtype) ((void)0)
00252
00253 #define SAME_THREAD(_a, _b) (42)
00254
00255 #define ME() __pid2vp(getpid())
00256
00257 static void *__pid2vp(pid_t pid)
00258
00259 {
00260 union { pid_t pid; void *vp; } u;
00261 u.pid = pid;
00262 return u.vp;
00263 }
00264
00265 #endif
00266
00267 #define _RPMSQ_INTERNAL
00268 #include <rpmsq.h>
00269
00270 #include "debug.h"
00271
00272 #define _RPMSQ_DEBUG 0
00273
00274 int _rpmsq_debug = _RPMSQ_DEBUG;
00275
00276
00277 static struct rpmsqElem rpmsqRock;
00278
00279
00280
00281 rpmsq rpmsqQueue = &rpmsqRock;
00282
00283
00284 int rpmsqInsert(void * elem, void * prev)
00285 {
00286 rpmsq sq = (rpmsq) elem;
00287 int ret = -1;
00288
00289 if (sq != NULL) {
00290 #ifdef _RPMSQ_DEBUG
00291 if (_rpmsq_debug)
00292 fprintf(stderr, " Insert(%p): %p\n", ME(), sq);
00293 #endif
00294 ret = sighold(SIGCHLD);
00295 if (ret == 0) {
00296 sq->child = 0;
00297 sq->reaped = 0;
00298 sq->status = 0;
00299
00300 sq->reaper = 1;
00301 sq->pipes[0] = sq->pipes[1] = -1;
00302
00303 sq->id = ME();
00304
00305 insque(elem, (prev != NULL ? prev : rpmsqQueue));
00306
00307 ret = sigrelse(SIGCHLD);
00308 }
00309 }
00310 return ret;
00311 }
00312
00313 int rpmsqRemove(void * elem)
00314 {
00315 rpmsq sq = (rpmsq) elem;
00316 int ret = -1;
00317
00318 if (elem != NULL) {
00319
00320 #ifdef _RPMSQ_DEBUG
00321 if (_rpmsq_debug)
00322 fprintf(stderr, " Remove(%p): %p\n", ME(), sq);
00323 #endif
00324 ret = sighold (SIGCHLD);
00325 if (ret == 0) {
00326
00327 remque(elem);
00328
00329 sq->id = NULL;
00330 if (sq->pipes[1] > 0) ret = close(sq->pipes[1]);
00331 if (sq->pipes[0] > 0) ret = close(sq->pipes[0]);
00332 sq->pipes[0] = sq->pipes[1] = -1;
00333 #ifdef NOTYET
00334 sq->status = 0;
00335 sq->reaped = 0;
00336 sq->child = 0;
00337 #endif
00338 ret = sigrelse(SIGCHLD);
00339 }
00340 }
00341 return ret;
00342 }
00343
00344
00345 sigset_t rpmsqCaught;
00346
00347
00348
00349 static struct rpmsig_s {
00350 int signum;
00351 void (*handler) (int signum, void * info, void * context);
00352 int active;
00353 struct sigaction oact;
00354 } rpmsigTbl[] = {
00355 { SIGINT, rpmsqAction },
00356 #define rpmsigTbl_sigint (&rpmsigTbl[0])
00357 { SIGQUIT, rpmsqAction },
00358 #define rpmsigTbl_sigquit (&rpmsigTbl[1])
00359 { SIGCHLD, rpmsqAction },
00360 #define rpmsigTbl_sigchld (&rpmsigTbl[2])
00361 { SIGHUP, rpmsqAction },
00362 #define rpmsigTbl_sighup (&rpmsigTbl[3])
00363 { SIGTERM, rpmsqAction },
00364 #define rpmsigTbl_sigterm (&rpmsigTbl[4])
00365 { SIGPIPE, rpmsqAction },
00366 #define rpmsigTbl_sigpipe (&rpmsigTbl[5])
00367 { -1, NULL },
00368 };
00369
00370
00371 void rpmsqAction(int signum,
00372 void * info, void * context)
00373 {
00374 int save = errno;
00375 rpmsig tbl;
00376
00377 for (tbl = rpmsigTbl; tbl->signum >= 0; tbl++) {
00378 if (tbl->signum != signum)
00379 continue;
00380
00381 (void) sigaddset(&rpmsqCaught, signum);
00382
00383 switch (signum) {
00384 case SIGCHLD:
00385 while (1) {
00386 rpmsq sq;
00387 int status = 0;
00388 pid_t reaped = waitpid(0, &status, WNOHANG);
00389
00390
00391 if (reaped <= 0)
00392 break;
00393
00394
00395 for (sq = rpmsqQueue->q_forw;
00396 sq != NULL && sq != rpmsqQueue;
00397 sq = sq->q_forw)
00398 {
00399 int ret;
00400
00401 if (sq->child != reaped)
00402 continue;
00403 sq->reaped = reaped;
00404 sq->status = status;
00405
00406 ret = close(sq->pipes[1]); sq->pipes[1] = -1;
00407
00408 break;
00409 }
00410 }
00411 break;
00412 default:
00413 break;
00414 }
00415 break;
00416 }
00417 errno = save;
00418 }
00419
00420 int rpmsqEnable(int signum, rpmsqAction_t handler)
00421
00422
00423 {
00424 int tblsignum = (signum >= 0 ? signum : -signum);
00425 struct sigaction sa;
00426 rpmsig tbl;
00427 int ret = -1;
00428
00429 (void) DO_LOCK ();
00430 if (rpmsqQueue->id == NULL)
00431 rpmsqQueue->id = ME();
00432 for (tbl = rpmsigTbl; tbl->signum >= 0; tbl++) {
00433 if (tblsignum != tbl->signum)
00434 continue;
00435
00436 if (signum >= 0) {
00437 if (ADD_REF(tbl) <= 0) {
00438 (void) sigdelset(&rpmsqCaught, tbl->signum);
00439
00440
00441 (void) sigaction(tbl->signum, NULL, &tbl->oact);
00442 if (tbl->oact.sa_handler == SIG_IGN)
00443 continue;
00444
00445 (void) sigemptyset (&sa.sa_mask);
00446 sa.sa_flags = SA_SIGINFO;
00447 #if defined(__LCLINT__)
00448 sa.sa_handler = (handler != NULL ? handler : tbl->handler);
00449 #else
00450 sa.sa_sigaction = (void *) (handler != NULL ? handler : tbl->handler);
00451 #endif
00452 if (sigaction(tbl->signum, &sa, &tbl->oact) < 0) {
00453 (void)SUB_REF(tbl);
00454 break;
00455 }
00456 tbl->active = 1;
00457 if (handler != NULL)
00458 tbl->handler = handler;
00459 }
00460 } else {
00461 if (SUB_REF(tbl) <= 0) {
00462 if (sigaction(tbl->signum, &tbl->oact, NULL) < 0)
00463 break;
00464 tbl->active = 0;
00465 tbl->handler = (handler != NULL ? handler : rpmsqAction);
00466 }
00467 }
00468 ret = tbl->active;
00469 break;
00470 }
00471 (void) DO_UNLOCK ();
00472 return ret;
00473 }
00474
00475 pid_t rpmsqFork(rpmsq sq)
00476 {
00477 pid_t pid;
00478 int xx;
00479
00480 if (sq->reaper) {
00481 xx = rpmsqInsert(sq, NULL);
00482 #ifdef _RPMSQ_DEBUG
00483 if (_rpmsq_debug)
00484 fprintf(stderr, " Enable(%p): %p\n", ME(), sq);
00485 #endif
00486 xx = rpmsqEnable(SIGCHLD, NULL);
00487 }
00488
00489 xx = pipe(sq->pipes);
00490
00491 xx = sighold(SIGCHLD);
00492
00493 pid = fork();
00494 if (pid < (pid_t) 0) {
00495 sq->child = (pid_t)-1;
00496 xx = close(sq->pipes[0]);
00497 xx = close(sq->pipes[1]);
00498 sq->pipes[0] = sq->pipes[1] = -1;
00499 goto out;
00500 } else if (pid == (pid_t) 0) {
00501 int yy;
00502
00503
00504 xx = close(sq->pipes[1]);
00505 if (sq->reaper)
00506 xx = (int)read(sq->pipes[0], &yy, sizeof(yy));
00507 xx = close(sq->pipes[0]);
00508 sq->pipes[0] = sq->pipes[1] = -1;
00509
00510 #ifdef _RPMSQ_DEBUG
00511 if (_rpmsq_debug)
00512 fprintf(stderr, " Child(%p): %p child %d\n", ME(), sq, (int)getpid());
00513 #endif
00514
00515 } else {
00516
00517 sq->child = pid;
00518
00519 #ifdef _RPMSQ_DEBUG
00520 if (_rpmsq_debug)
00521 fprintf(stderr, " Parent(%p): %p child %d\n", ME(), sq, (int)sq->child);
00522 #endif
00523
00524 }
00525
00526 out:
00527 xx = sigrelse(SIGCHLD);
00528 return sq->child;
00529 }
00530
00537 static int rpmsqWaitUnregister(rpmsq sq)
00538
00539
00540 {
00541 int nothreads = 0;
00542 int ret = 0;
00543 int xx;
00544
00545 assert(sq->reaper);
00546
00547 ret = sighold(SIGCHLD);
00548
00549
00550 if (sq->pipes[0] >= 0)
00551 xx = close(sq->pipes[0]);
00552 if (sq->pipes[1] >= 0)
00553 xx = close(sq->pipes[1]);
00554
00555
00556 xx = pipe(sq->pipes);
00557
00558
00559 (void) rpmswEnter(&sq->op, -1);
00560
00561
00562
00563 while (ret == 0 && sq->reaped != sq->child) {
00564 if (nothreads)
00565
00566 ret = sigpause(SIGCHLD);
00567 else {
00568 xx = sigrelse(SIGCHLD);
00569
00570
00571 if (read(sq->pipes[0], &xx, sizeof(xx)) == 0) {
00572 xx = close(sq->pipes[0]); sq->pipes[0] = -1;
00573 ret = 1;
00574 }
00575
00576 xx = sighold(SIGCHLD);
00577 }
00578 }
00579
00580
00581
00582 sq->ms_scriptlets += rpmswExit(&sq->op, -1)/1000;
00583
00584 xx = sigrelse(SIGCHLD);
00585
00586 #ifdef _RPMSQ_DEBUG
00587 if (_rpmsq_debug)
00588 fprintf(stderr, " Wake(%p): %p child %d reaper %d ret %d\n", ME(), sq, (int)sq->child, sq->reaper, ret);
00589 #endif
00590
00591
00592 xx = rpmsqRemove(sq);
00593
00594
00595 xx = rpmsqEnable(-SIGCHLD, NULL);
00596 #ifdef _RPMSQ_DEBUG
00597 if (_rpmsq_debug)
00598 fprintf(stderr, " Disable(%p): %p\n", ME(), sq);
00599 #endif
00600
00601 return ret;
00602 }
00603
00604 pid_t rpmsqWait(rpmsq sq)
00605 {
00606
00607 #ifdef _RPMSQ_DEBUG
00608 if (_rpmsq_debug)
00609 fprintf(stderr, " Wait(%p): %p child %d reaper %d\n", ME(), sq, (int)sq->child, sq->reaper);
00610 #endif
00611
00612 if (sq->reaper) {
00613 (void) rpmsqWaitUnregister(sq);
00614 } else {
00615 pid_t reaped;
00616 int status;
00617 do {
00618 reaped = waitpid(sq->child, &status, 0);
00619 } while (reaped >= 0 && reaped != sq->child);
00620 sq->reaped = reaped;
00621 sq->status = status;
00622 #ifdef _RPMSQ_DEBUG
00623 if (_rpmsq_debug)
00624 fprintf(stderr, " Waitpid(%p): %p child %d reaped %d\n", ME(), sq, (int)sq->child, (int)sq->reaped);
00625 #endif
00626 }
00627
00628 #ifdef _RPMSQ_DEBUG
00629 if (_rpmsq_debug)
00630 fprintf(stderr, " Fini(%p): %p child %d status 0x%x\n", ME(), sq, (int)sq->child, sq->status);
00631 #endif
00632
00633 return sq->reaped;
00634 }
00635
00636 void * rpmsqThread(void * (*start) (void * arg), void * arg)
00637 {
00638 #if defined(HAVE_PTHREAD_H)
00639 pthread_t pth;
00640 int ret;
00641
00642 ret = pthread_create(&pth, NULL, start, arg);
00643 return (ret == 0 ? (void *)pth : NULL);
00644 #else
00645 return NULL;
00646 #endif
00647 }
00648
00649 int rpmsqJoin(void * thread)
00650 {
00651 #if defined(HAVE_PTHREAD_H)
00652 pthread_t pth = (pthread_t) thread;
00653 if (thread == NULL)
00654 return EINVAL;
00655 return pthread_join(pth, NULL);
00656 #else
00657 return EINVAL;
00658 #endif
00659 }
00660
00661 int rpmsqThreadEqual(void * thread)
00662 {
00663 #if defined(HAVE_PTHREAD_H)
00664 pthread_t t1 = (pthread_t) thread;
00665 pthread_t t2 = pthread_self();
00666 return pthread_equal(t1, t2);
00667 #else
00668 return 0;
00669 #endif
00670 }
00671
00675 #if defined(HAVE_PTHREAD_H)
00676 static void
00677 sigchld_cancel (void *arg)
00678
00679
00680 {
00681 pid_t child = *(pid_t *) arg;
00682 pid_t result;
00683
00684 (void) kill(child, SIGKILL);
00685
00686 do {
00687 result = waitpid(child, NULL, 0);
00688 } while (result == (pid_t)-1 && errno == EINTR);
00689
00690 (void) DO_LOCK ();
00691 if (SUB_REF (rpmsigTbl_sigchld) == 0) {
00692 (void) rpmsqEnable(-SIGQUIT, NULL);
00693 (void) rpmsqEnable(-SIGINT, NULL);
00694 }
00695 (void) DO_UNLOCK ();
00696 }
00697 #endif
00698
00702 int
00703 rpmsqExecve (const char ** argv)
00704
00705
00706 {
00707 #if defined(HAVE_PTHREAD_H)
00708 int oldtype;
00709 #endif
00710 int status = -1;
00711 pid_t pid = 0;
00712 pid_t result;
00713 sigset_t newMask, oldMask;
00714 rpmsq sq = memset(alloca(sizeof(*sq)), 0, sizeof(*sq));
00715
00716 #ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
00717 INIT_LOCK ();
00718 #endif
00719
00720 (void) DO_LOCK ();
00721 if (ADD_REF (rpmsigTbl_sigchld) == 0) {
00722 if (rpmsqEnable(SIGINT, NULL) < 0) {
00723 (void) SUB_REF (rpmsigTbl_sigchld);
00724 goto out;
00725 }
00726 if (rpmsqEnable(SIGQUIT, NULL) < 0) {
00727 (void) SUB_REF (rpmsigTbl_sigchld);
00728 goto out_restore_sigint;
00729 }
00730 }
00731 (void) DO_UNLOCK ();
00732
00733 (void) sigemptyset (&newMask);
00734 (void) sigaddset (&newMask, SIGCHLD);
00735 if (sigprocmask (SIG_BLOCK, &newMask, &oldMask) < 0) {
00736 (void) DO_LOCK ();
00737 if (SUB_REF (rpmsigTbl_sigchld) == 0)
00738 goto out_restore_sigquit_and_sigint;
00739 goto out;
00740 }
00741
00742
00743 CLEANUP_HANDLER(sigchld_cancel, &pid, &oldtype);
00744
00745
00746 pid = fork ();
00747 if (pid < (pid_t) 0) {
00748 goto out;
00749 } else if (pid == (pid_t) 0) {
00750
00751
00752 (void) sigaction (SIGINT, &rpmsigTbl_sigint->oact, NULL);
00753 (void) sigaction (SIGQUIT, &rpmsigTbl_sigquit->oact, NULL);
00754 (void) sigprocmask (SIG_SETMASK, &oldMask, NULL);
00755
00756
00757 INIT_LOCK ();
00758
00759 (void) execve (argv[0], (char *const *) argv, environ);
00760 _exit (127);
00761 } else {
00762 do {
00763 result = waitpid(pid, &status, 0);
00764 } while (result == (pid_t)-1 && errno == EINTR);
00765 if (result != pid)
00766 status = -1;
00767 }
00768
00769 CLEANUP_RESET(0, oldtype);
00770
00771 (void) DO_LOCK ();
00772 if ((SUB_REF (rpmsigTbl_sigchld) == 0 &&
00773 (rpmsqEnable(-SIGINT, NULL) < 0 || rpmsqEnable (-SIGQUIT, NULL) < 0))
00774 || sigprocmask (SIG_SETMASK, &oldMask, NULL) != 0)
00775 {
00776 status = -1;
00777 }
00778 goto out;
00779
00780 out_restore_sigquit_and_sigint:
00781 (void) rpmsqEnable(-SIGQUIT, NULL);
00782 out_restore_sigint:
00783 (void) rpmsqEnable(-SIGINT, NULL);
00784 out:
00785 (void) DO_UNLOCK ();
00786 return status;
00787 }