Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP1:Update
psmisc
psmisc-23.0-semaphores.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File psmisc-23.0-semaphores.patch of Package psmisc
Use semaphores for synchronize the stating sub process --- Makefile.am | 2 src/timeout.c | 130 ++++++++++++++++++++++++---------------------------------- 2 files changed, 56 insertions(+), 76 deletions(-) --- Makefile.am +++ Makefile.am 2022-03-02 14:48:10.996587471 +0000 @@ -61,7 +61,7 @@ src_fuser_SOURCES = \ if WANT_TIMEOUT_STAT src_fuser_SOURCES += src/timeout.c src/timeout.h endif -src_fuser_LDADD = @LIBINTL@ +src_fuser_LDADD = @LIBINTL@ -lpthread src_killall_SOURCES = src/killall.c src/comm.h src/signals.c src/signals.h src/i18n.h src_killall_LDADD = @LIBINTL@ @SELINUX_LIB@ src_peekfd_SOURCES = src/peekfd.c --- src/timeout.c +++ src/timeout.c 2022-03-01 09:05:31.374592643 +0000 @@ -27,11 +27,8 @@ # define WITH_TIMEOUT_STAT 0 #endif -#ifndef USE_SOCKETPAIR -# define USE_SOCKETPAIR 1 -#endif - #include <errno.h> +#include <pthread.h> #include <setjmp.h> #include <signal.h> #include <stdlib.h> @@ -42,20 +39,6 @@ #include <sys/select.h> #include <sys/stat.h> #include <unistd.h> -#if USE_SOCKETPAIR -# include <sys/socket.h> -# include <netdb.h> -# include <netinet/in.h> -# ifndef SHUT_RD -# define SHUT_RD 0 -# endif -# ifndef SHUT_WR -# define SHUT_WR 1 -# endif -# undef pipe -# define pipe(v) (((socketpair(AF_UNIX,SOCK_STREAM,0,v) < 0) || \ - (shutdown((v)[1],SHUT_RD) < 0) || (shutdown((v)[0],SHUT_WR) < 0)) ? -1 : 0) -#endif #include <wait.h> #include "timeout.h" @@ -102,6 +85,10 @@ static void sigjump(int sig attribute((u * The structure used for communication between the processes */ typedef struct _handle { + pthread_mutex_t mutex; + pthread_cond_t waiton, result; + volatile int todo; + pid_t active; int errcode; struct stat argument; stat_t function; @@ -117,8 +104,7 @@ typedef struct _handle { */ static volatile pid_t active; -static int pipes[4] = {-1, -1, -1, -1}; -static handle_t *restrict handle; +static handle_t *handle; static const size_t buflen = PATH_MAX+sizeof(handle_t)+1; static void sigchild(int sig attribute((unused))) @@ -135,16 +121,8 @@ static void attribute((constructor)) sta { sigset_t sigset, oldset; struct sigaction act; - char sync[1]; - ssize_t in; - - if (pipes[1] >= 0) close(pipes[1]); - if (pipes[2] >= 0) close(pipes[2]); - - if (pipe(&pipes[0])) - goto error; - if (pipe(&pipes[2])) - goto error; + pthread_mutexattr_t mattr; + pthread_condattr_t cattr; memset(&act, 0, sizeof(act)); sigemptyset(&act.sa_mask); @@ -152,22 +130,40 @@ static void attribute((constructor)) sta act.sa_handler = sigchild; sigaction(SIGCHLD, &act, 0); - if (!handle) + if (!handle) { handle = mmap(NULL, buflen, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_SHARED, -1, 0); - if (handle == MAP_FAILED) - goto error; + if (handle == MAP_FAILED) + goto error; + memset(handle, 0, buflen); + + if (pthread_mutexattr_init(&mattr) < 0) + goto error; + if (pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED) < 0) + goto error; + if (pthread_mutex_init(&handle->mutex, &mattr) < 0) + goto error; + pthread_mutexattr_destroy(&mattr); + + if (pthread_condattr_init(&cattr) < 0) + goto error; + if (pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_SHARED) < 0) + goto error; + if (pthread_cond_init(&handle->waiton, &cattr) < 0) + goto error; + if (pthread_cond_init(&handle->result, &cattr) < 0) + goto error; + pthread_condattr_destroy(&cattr); + } + handle->todo = 0; if ((active = fork()) < 0) goto error; if (active) { - close(pipes[0]); - close(pipes[3]); - pipes[0] = pipes[3] = -1; + handle->active = active; return; } - sigemptyset(&sigset); sigaddset(&sigset, SIGALRM); sigprocmask(SIG_BLOCK, &sigset, &oldset); @@ -175,44 +171,29 @@ static void attribute((constructor)) sta act.sa_handler = SIG_DFL; sigaction(SIGCHLD, &act, 0); - close(pipes[1]); - close(pipes[2]); - dup2(pipes[0], STDIN_FILENO); - dup2(pipes[3], STDOUT_FILENO); - close(pipes[0]); - close(pipes[3]); - pipes[1] = pipes[2] = -1; - pipes[0] = pipes[3] = -1; - - while ((in = read(STDIN_FILENO, &sync, sizeof(sync))) != 0) { - ssize_t out; - if (in < 0) { - if (errno == EINTR) - continue; - break; - } - if (!handle) - break; + do { + pthread_mutex_lock(&handle->mutex); + while (!handle->todo) + pthread_cond_wait(&handle->waiton, &handle->mutex); + if (handle->function(handle->path, &handle->argument) < 0) - handle->errcode = errno; - do - out = write(STDOUT_FILENO, &sync, sizeof(sync)); - while (out < 0 && errno == EINTR); - } + handle->errcode = errno; + + handle->todo = 0; + pthread_cond_broadcast(&handle->result); + pthread_mutex_unlock(&handle->mutex); + + } while (handle->active); sigprocmask(SIG_SETMASK, &oldset, NULL); exit(0); error: - if (pipes[0] >= 0) close(pipes[0]); - if (pipes[1] >= 0) close(pipes[1]); - if (pipes[2] >= 0) close(pipes[2]); - if (pipes[3] >= 0) close(pipes[3]); if (handle && handle != MAP_FAILED) munmap(handle, buflen); handle = NULL; } -static void /* attribute((destructor)) */ stop(void) +static void attribute((destructor)) stop(void) { if (active && waitpid(active, NULL, WNOHANG|WUNTRACED) == 0) kill(active, SIGKILL); @@ -228,15 +209,14 @@ static void /* attribute((destructor)) * int timeout(stat_t function, const char *path, struct stat *restrict argument, time_t seconds) { - struct sigaction alrm_act, pipe_act, new_act; + struct sigaction alrm_act, new_act; sigset_t sigset, oldset; - char sync[1] = "x"; if (active <= 0) /* Oops, last one failed therefore clear status and restart */ start(); if (!handle) /* No shared memory area */ return function(path, argument); - memset(handle, 0, sizeof(handle_t)); + handle->len = strlen(path) + 1; if (handle->len >= PATH_MAX) { errno = ENAMETOOLONG; @@ -249,26 +229,27 @@ timeout(stat_t function, const char *pat sigemptyset(&sigset); sigaddset(&sigset, SIGALRM); - sigaddset(&sigset, SIGPIPE); + sigaddset(&sigset, SIGINT); sigprocmask(SIG_UNBLOCK, &sigset, &oldset); memset(&new_act, 0, sizeof(new_act)); sigemptyset(&new_act.sa_mask); new_act.sa_flags = SA_RESETHAND; - if (sigsetjmp(jenv, 1)) goto timed; new_act.sa_handler = sigjump; sigaction(SIGALRM, &new_act, &alrm_act); - sigaction(SIGPIPE, &new_act, &pipe_act); alarm(seconds); - write(pipes[1], &sync, sizeof(sync)); - read(pipes[2], &sync, sizeof(sync)); + pthread_mutex_lock(&handle->mutex); + handle->todo = 1; + pthread_cond_broadcast(&handle->waiton); + while (handle->todo) + pthread_cond_wait(&handle->result, &handle->mutex); + pthread_mutex_unlock(&handle->mutex); alarm(0); - sigaction(SIGPIPE, &pipe_act, NULL); sigaction(SIGALRM, &alrm_act, NULL); if (handle->errcode) { @@ -282,7 +263,6 @@ timeout(stat_t function, const char *pat return 0; timed: (void) alarm(0); - sigaction(SIGPIPE, &pipe_act, NULL); sigaction(SIGALRM, &alrm_act, NULL); sigprocmask(SIG_SETMASK, &oldset, NULL); stop();
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor