diff options
author | Eric Andersen <andersen@codepoet.org> | 2006-12-07 23:24:02 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2006-12-07 23:24:02 +0000 |
commit | 1478c2de052374c6356db5513749a144c13791b1 (patch) | |
tree | 3b22a3f8361f94c99508c497e240ecb71acf8641 /libc/pwd_grp | |
parent | 99d6c367c4820a072dc4ada51561df17e2093778 (diff) |
Major cleanup of internal mutex locking. Be more consistant in how we do
things, and avoid potential deadlocks caused when a thread holding a uClibc
internal lock get canceled and terminates without releasing the lock. This
change also provides a single place, bits/uClibc_mutex.h, for thread libraries
to modify to change all instances of internal locking.
Diffstat (limited to 'libc/pwd_grp')
-rw-r--r-- | libc/pwd_grp/lckpwdf.c | 37 | ||||
-rw-r--r-- | libc/pwd_grp/pwd_grp.c | 97 |
2 files changed, 60 insertions, 74 deletions
diff --git a/libc/pwd_grp/lckpwdf.c b/libc/pwd_grp/lckpwdf.c index 2d38e89f9..f241cdffc 100644 --- a/libc/pwd_grp/lckpwdf.c +++ b/libc/pwd_grp/lckpwdf.c @@ -48,12 +48,8 @@ libc_hidden_proto(alarm) static int lock_fd = -1; /* Prevent problems in multithreaded program by using mutex. */ -#ifdef __UCLIBC_HAS_THREADS__ -# include <pthread.h> -static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; -#endif -#define LOCK __pthread_mutex_lock(&mylock) -#define UNLOCK __pthread_mutex_unlock(&mylock) +#include <bits/uClibc_mutex.h> +__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); /* Prototypes for local functions. */ @@ -70,19 +66,19 @@ lckpwdf (void) struct sigaction new_act; /* New signal action. */ struct flock fl; /* Information struct for locking. */ int result; + int rv = -1; if (lock_fd != -1) /* Still locked by own process. */ return -1; /* Prevent problems caused by multiple threads. */ - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); lock_fd = open (_PATH_PASSWD, O_WRONLY); if (lock_fd == -1) { /* Cannot create lock file. */ - UNLOCK; - return -1; + goto DONE; } /* Make sure file gets correctly closed when process finished. */ @@ -91,16 +87,14 @@ lckpwdf (void) /* Cannot get file flags. */ close(lock_fd); lock_fd = -1; - UNLOCK; - return -1; + goto DONE; } flags |= FD_CLOEXEC; /* Close on exit. */ if (fcntl (lock_fd, F_SETFD, flags) < 0) { /* Cannot set new flags. */ close(lock_fd); lock_fd = -1; - UNLOCK; - return -1; + goto DONE; } /* Now we have to get exclusive write access. Since multiple @@ -121,8 +115,7 @@ lckpwdf (void) /* Cannot install signal handler. */ close(lock_fd); lock_fd = -1; - UNLOCK; - return -1; + goto DONE; } /* Now make sure the alarm signal is not blocked. */ @@ -132,8 +125,7 @@ lckpwdf (void) sigaction (SIGALRM, &saved_act, NULL); close(lock_fd); lock_fd = -1; - UNLOCK; - return -1; + goto DONE; } /* Start timer. If we cannot get the lock in the specified time we @@ -160,11 +152,12 @@ lckpwdf (void) if (result < 0) { close(lock_fd); lock_fd = -1; - UNLOCK; - return -1; + goto DONE; } + rv = 0; - UNLOCK; +DONE: + __UCLIBC_MUTEX_UNLOCK(mylock); return 0; } @@ -180,7 +173,7 @@ ulckpwdf (void) else { /* Prevent problems caused by multiple threads. */ - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); result = close (lock_fd); @@ -188,7 +181,7 @@ ulckpwdf (void) lock_fd = -1; /* Clear mutex. */ - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); } return result; diff --git a/libc/pwd_grp/pwd_grp.c b/libc/pwd_grp/pwd_grp.c index 2a9d4519a..d223a9e36 100644 --- a/libc/pwd_grp/pwd_grp.c +++ b/libc/pwd_grp/pwd_grp.c @@ -34,9 +34,7 @@ #ifdef __UCLIBC_HAS_SHADOW__ #include <shadow.h> #endif -#ifdef __UCLIBC_HAS_THREADS__ -#include <pthread.h> -#endif +#include <bits/uClibc_mutex.h> libc_hidden_proto(strchr) libc_hidden_proto(strcmp) @@ -253,7 +251,7 @@ libc_hidden_def(sgetspent_r) #ifdef L_getpwnam_r #define GETXXKEY_R_FUNC getpwnam_r -#define GETXXKEY_R_PARSER __parsepwent +#define GETXXKEY_R_PARSER __parsepwent #define GETXXKEY_R_ENTTYPE struct passwd #define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->pw_name, key)) #define DO_GETXXKEY_R_KEYTYPE const char *__restrict @@ -263,7 +261,7 @@ libc_hidden_def(sgetspent_r) #ifdef L_getgrnam_r #define GETXXKEY_R_FUNC getgrnam_r -#define GETXXKEY_R_PARSER __parsegrent +#define GETXXKEY_R_PARSER __parsegrent #define GETXXKEY_R_ENTTYPE struct group #define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->gr_name, key)) #define DO_GETXXKEY_R_KEYTYPE const char *__restrict @@ -273,7 +271,7 @@ libc_hidden_def(sgetspent_r) #ifdef L_getspnam_r #define GETXXKEY_R_FUNC getspnam_r -#define GETXXKEY_R_PARSER __parsespent +#define GETXXKEY_R_PARSER __parsespent #define GETXXKEY_R_ENTTYPE struct spwd #define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->sp_namp, key)) #define DO_GETXXKEY_R_KEYTYPE const char *__restrict @@ -283,7 +281,7 @@ libc_hidden_def(sgetspent_r) #ifdef L_getpwuid_r #define GETXXKEY_R_FUNC getpwuid_r -#define GETXXKEY_R_PARSER __parsepwent +#define GETXXKEY_R_PARSER __parsepwent #define GETXXKEY_R_ENTTYPE struct passwd #define GETXXKEY_R_TEST(ENT) ((ENT)->pw_uid == key) #define DO_GETXXKEY_R_KEYTYPE uid_t @@ -293,7 +291,7 @@ libc_hidden_def(sgetspent_r) #ifdef L_getgrgid_r #define GETXXKEY_R_FUNC getgrgid_r -#define GETXXKEY_R_PARSER __parsegrent +#define GETXXKEY_R_PARSER __parsegrent #define GETXXKEY_R_ENTTYPE struct group #define GETXXKEY_R_TEST(ENT) ((ENT)->gr_gid == key) #define DO_GETXXKEY_R_KEYTYPE gid_t @@ -458,47 +456,40 @@ int getpw(uid_t uid, char *buf) #endif /**********************************************************************/ -#if defined(L_getpwent_r) || defined(L_getgrent_r) || defined(L_getspent_r) -#ifdef __UCLIBC_HAS_THREADS__ -# include <pthread.h> -static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; -#endif -#define LOCK __pthread_mutex_lock(&mylock) -#define UNLOCK __pthread_mutex_unlock(&mylock) -#endif #ifdef L_getpwent_r +__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); static FILE *pwf /*= NULL*/; void setpwent(void) { - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); if (pwf) { rewind(pwf); } - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); } void endpwent(void) { - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); if (pwf) { fclose(pwf); pwf = NULL; } - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); } libc_hidden_proto(getpwent_r) -int getpwent_r(struct passwd *__restrict resultbuf, +int getpwent_r(struct passwd *__restrict resultbuf, char *__restrict buffer, size_t buflen, struct passwd **__restrict result) { int rv; - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); *result = NULL; /* In case of error... */ @@ -516,7 +507,7 @@ int getpwent_r(struct passwd *__restrict resultbuf, } ERR: - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); return rv; } @@ -525,26 +516,27 @@ libc_hidden_def(getpwent_r) #endif /**********************************************************************/ #ifdef L_getgrent_r +__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); static FILE *grf /*= NULL*/; void setgrent(void) { - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); if (grf) { rewind(grf); } - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); } void endgrent(void) { - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); if (grf) { fclose(grf); grf = NULL; } - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); } libc_hidden_proto(getgrent_r) @@ -554,7 +546,7 @@ int getgrent_r(struct group *__restrict resultbuf, { int rv; - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); *result = NULL; /* In case of error... */ @@ -572,7 +564,7 @@ int getgrent_r(struct group *__restrict resultbuf, } ERR: - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); return rv; } @@ -581,35 +573,36 @@ libc_hidden_def(getgrent_r) #endif /**********************************************************************/ #ifdef L_getspent_r +__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); static FILE *spf /*= NULL*/; void setspent(void) { - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); if (spf) { rewind(spf); } - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); } void endspent(void) { - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); if (spf) { fclose(spf); spf = NULL; } - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); } libc_hidden_proto(getspent_r) -int getspent_r(struct spwd *resultbuf, char *buffer, +int getspent_r(struct spwd *resultbuf, char *buffer, size_t buflen, struct spwd **result) { int rv; - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); *result = NULL; /* In case of error... */ @@ -627,7 +620,7 @@ int getspent_r(struct spwd *resultbuf, char *buffer, } ERR: - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); return rv; } @@ -842,11 +835,11 @@ int putgrent(const struct group *__restrict p, FILE *__restrict f) static const unsigned char _sp_off[] = { offsetof(struct spwd, sp_lstchg), /* 2 - not a char ptr */ - offsetof(struct spwd, sp_min), /* 3 - not a char ptr */ + offsetof(struct spwd, sp_min), /* 3 - not a char ptr */ offsetof(struct spwd, sp_max), /* 4 - not a char ptr */ - offsetof(struct spwd, sp_warn), /* 5 - not a char ptr */ - offsetof(struct spwd, sp_inact), /* 6 - not a char ptr */ - offsetof(struct spwd, sp_expire), /* 7 - not a char ptr */ + offsetof(struct spwd, sp_warn), /* 5 - not a char ptr */ + offsetof(struct spwd, sp_inact), /* 6 - not a char ptr */ + offsetof(struct spwd, sp_expire), /* 7 - not a char ptr */ }; int putspent(const struct spwd *p, FILE *stream) @@ -899,13 +892,13 @@ int putspent(const struct spwd *p, FILE *stream) #ifdef L___parsepwent static const unsigned char pw_off[] = { - offsetof(struct passwd, pw_name), /* 0 */ + offsetof(struct passwd, pw_name), /* 0 */ offsetof(struct passwd, pw_passwd), /* 1 */ offsetof(struct passwd, pw_uid), /* 2 - not a char ptr */ - offsetof(struct passwd, pw_gid), /* 3 - not a char ptr */ + offsetof(struct passwd, pw_gid), /* 3 - not a char ptr */ offsetof(struct passwd, pw_gecos), /* 4 */ - offsetof(struct passwd, pw_dir), /* 5 */ - offsetof(struct passwd, pw_shell) /* 6 */ + offsetof(struct passwd, pw_dir), /* 5 */ + offsetof(struct passwd, pw_shell) /* 6 */ }; int attribute_hidden __parsepwent(void *data, char *line) @@ -918,7 +911,7 @@ int attribute_hidden __parsepwent(void *data, char *line) do { p = ((char *) ((struct passwd *) data)) + pw_off[i]; - if ((i & 6) ^ 2) { /* i!=2 and i!=3 */ + if ((i & 6) ^ 2) { /* i!=2 and i!=3 */ *((char **) p) = line; if (i==6) { return 0; @@ -958,7 +951,7 @@ int attribute_hidden __parsepwent(void *data, char *line) #ifdef L___parsegrent static const unsigned char gr_off[] = { - offsetof(struct group, gr_name), /* 0 */ + offsetof(struct group, gr_name), /* 0 */ offsetof(struct group, gr_passwd), /* 1 */ offsetof(struct group, gr_gid) /* 2 - not a char ptr */ }; @@ -1040,7 +1033,7 @@ int attribute_hidden __parsegrent(void *data, char *line) if (!--i) break; while (*++p) {} } while (1); - } + } *members = NULL; return 0; @@ -1059,12 +1052,12 @@ static const unsigned char sp_off[] = { offsetof(struct spwd, sp_namp), /* 0 */ offsetof(struct spwd, sp_pwdp), /* 1 */ offsetof(struct spwd, sp_lstchg), /* 2 - not a char ptr */ - offsetof(struct spwd, sp_min), /* 3 - not a char ptr */ + offsetof(struct spwd, sp_min), /* 3 - not a char ptr */ offsetof(struct spwd, sp_max), /* 4 - not a char ptr */ - offsetof(struct spwd, sp_warn), /* 5 - not a char ptr */ - offsetof(struct spwd, sp_inact), /* 6 - not a char ptr */ - offsetof(struct spwd, sp_expire), /* 7 - not a char ptr */ - offsetof(struct spwd, sp_flag) /* 8 - not a char ptr */ + offsetof(struct spwd, sp_warn), /* 5 - not a char ptr */ + offsetof(struct spwd, sp_inact), /* 6 - not a char ptr */ + offsetof(struct spwd, sp_expire), /* 7 - not a char ptr */ + offsetof(struct spwd, sp_flag) /* 8 - not a char ptr */ }; int attribute_hidden __parsespent(void *data, char * line) |