Fixes for some minro thread-safety issues.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@25759 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2007-12-19 14:39:44 +00:00
parent 16e6526498
commit e980ba412c
14 changed files with 7195 additions and 6812 deletions

View file

@ -1,3 +1,23 @@
2007-12-19 Richard Frith-Macdonald <rfm@gnu.org>
* configure.ac: Add checks for thread-safe versions of some standard
library functions.
* Headers/Additions/GNUstepBase/config.h.in: Regenerate
* configure: Regenerate
* Source/NSPathUtilities.m:
* Source/NSProcessInfo.m:
* Source/NSFileManager.m:
* Source/externs.m:
* Source/Additions/GSObjCRuntime.m:
* Source/Additions/GSCategories.m:
* Source/Additions/GSLock.m:
* Headers/Foundation/NSObject.h:
* Headers/Additions/GNUstepBase/GSLock.h:
* Tools/defaults.m:
Use thread-safe variants of system functions or pretect unsafe ones
using gnustep_global_lock.
Fixes part (but not all) of bug #21320
2007-12-17 Fred Kiefer <FredKiefer@gmx.de>
* Source/NSKeyValueObserving.m

View file

@ -54,6 +54,11 @@ extern "C" {
- (void) _becomeThreaded: (NSNotification*)n;
@end
/** Global lock to be used by classes when operating on any global
data that invoke other methods which also access global; thus,
creating the potential for deadlock. */
GS_EXPORT NSRecursiveLock *gnustep_global_lock;
#if defined(__cplusplus)
}
#endif

View file

@ -208,6 +208,18 @@
/* Define to 1 if you have the `getgrgid' function. */
#undef HAVE_GETGRGID
/* Define to 1 if you have the `getgrgid_r' function. */
#undef HAVE_GETGRGID_R
/* Define to 1 if you have the `getgrnam' function. */
#undef HAVE_GETGRNAM
/* Define to 1 if you have the `getgrnam_r' function. */
#undef HAVE_GETGRNAM_R
/* Define to 1 if you have the `gethostbyaddr_r' function. */
#undef HAVE_GETHOSTBYADDR_R
/* Define to 1 if you have the `getlogin' function. */
#undef HAVE_GETLOGIN
@ -220,9 +232,15 @@
/* Define to 1 if you have the `getpwnam' function. */
#undef HAVE_GETPWNAM
/* Define to 1 if you have the `getpwnam_r' function. */
#undef HAVE_GETPWNAM_R
/* Define to 1 if you have the `getpwuid' function. */
#undef HAVE_GETPWUID
/* Define to 1 if you have the `getpwuid_r' function. */
#undef HAVE_GETPWUID_R
/* Define if you have this function */
#undef HAVE_GICONV
@ -238,6 +256,9 @@
/* Define to 1 if you have the `inet_aton' function. */
#undef HAVE_INET_ATON
/* Define to 1 if you have the `inet_ntop' function. */
#undef HAVE_INET_NTOP
/* Define to 1 if you have the `inet_pton' function. */
#undef HAVE_INET_PTON
@ -400,6 +421,9 @@
/* Define to 1 if you have the `strerror' function. */
#undef HAVE_STRERROR
/* Define to 1 if you have the `strerror_r' function. */
#undef HAVE_STRERROR_R
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H

View file

@ -291,17 +291,17 @@ enum {NSNotFound = 0x7fffffff};
#if OS_API_VERSION(GS_API_NONE, GS_API_NONE)
/** Global lock to be used by classes when operating on any global
data that invoke other methods which also access global; thus,
creating the potential for deadlock. */
GS_EXPORT NSRecursiveLock *gnustep_global_lock;
@interface NSObject (NEXTSTEP)
- error:(const char *)aString, ...;
/* - (const char *) name;
Removed because OpenStep has -(NSString*)name; */
@end
/** Global lock to be used by classes when operating on any global
data that invoke other methods which also access global; thus,
creating the potential for deadlock. */
GS_EXPORT NSRecursiveLock *gnustep_global_lock;
@interface NSObject (GNUstep)
- (BOOL) isInstance;
- (id) makeImmutableCopyOnFail: (BOOL)force;

View file

@ -908,20 +908,46 @@ static void MD5Transform (uint32_t buf[4], uint32_t const in[16])
*/
@implementation NSError(GSCategories)
#ifndef HAVE_STRERROR
static const char *
strerror(int eno)
#ifndef HAVE_STRERROR_R
#ifdef HAVE_STRERROR
static int
strerror_r(int eno, char *buf, int len)
{
const char *ptr;
int result;
[gnustep_global_lock lock];
ptr = strerror(eno);
if (ptr == 0)
{
strncpy(buf, "unknown error number", len);
result = -1;
}
else
{
strncpy(buf, strerror(eno), len);
result = 0;
}
[gnustep_global_lock unlock];
return result;
}
#else
static int
strerror_r(int eno, char *buf, int len)
{
extern char *sys_errlist[];
extern int sys_nerr;
if (eno < 0 || eno >= sys_nerr)
{
return("unknown error number");
strncpy(buf, "unknown error number", len);
return -1;
}
return(sys_errlist[eno]);
strncpy(buf, sys_errlist[eno], len);
return 0;
}
#endif
#endif
/*
* Returns an NSError instance encapsulating the last system error.
@ -959,10 +985,15 @@ strerror(int eno)
nil];
#else
NSString *message;
char buf[BUFSIZ];
/* FIXME ... not all are POSIX, should we use NSMachErrorDomain for some? */
domain = NSPOSIXErrorDomain;
message = [NSString stringWithCString: strerror(code)
if (strerror_r(code, buf, BUFSIZ) < 0)
{
sprintf(buf, "%ld", code);
}
message = [NSString stringWithCString: buf
encoding: [NSString defaultCStringEncoding]];
/* FIXME ... can we do better localisation? */
info = [NSMutableDictionary dictionaryWithObjectsAndKeys:

View file

@ -19,7 +19,8 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA.
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02111 USA.
$Date$ $Revision$
*/
@ -315,3 +316,8 @@
@end
/* Global lock to be used by classes when operating on any global
data that invoke other methods which also access global; thus,
creating the potential for deadlock. */
NSRecursiveLock *gnustep_global_lock = nil;

View file

@ -52,6 +52,8 @@
#include "GNUstepBase/GNUstep.h"
#include "GNUstepBase/GSCategories.h"
#include "../GSPrivate.h"
#include <objc/Protocol.h>
#include <string.h>
@ -976,7 +978,7 @@ GSMethodFromList(GSMethodList list,
/* For the GNU runtime we have use strcmp instead of sel_eq
for free standing method lists. */
if ((isFree == YES && strcmp((char *)method_name, (char *)sel) == 0)
|| (isFree == NO && sel_eq(method_name, sel)))
|| (isFree == NO && sel_eq(method_name, sel)))
{
return method;
}
@ -2204,52 +2206,12 @@ GSAutoreleasedBuffer(unsigned size)
/*
* Getting a system error message on a variety of systems.
* Currently 8bit string ... perhaps we should move to unicode.
* Deprecated function.
*/
#ifdef __MINGW32__
const char *GetErrorMsg(DWORD msgId)
{
void *lpMsgBuf = 0;
FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
msgId,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPSTR)&lpMsgBuf,
(DWORD)0,
NULL);
return (const char*)lpMsgBuf;
}
#else
#ifndef HAVE_STRERROR
const char *
strerror(int eno)
{
extern char *sys_errlist[];
extern int sys_nerr;
if (eno < 0 || eno >= sys_nerr)
{
return("unknown error number");
}
return(sys_errlist[eno]);
}
#endif
#endif /* __MINGW32__ */
const char *
GSLastErrorStr(long error_id)
{
#ifdef __MINGW32__
return GetErrorMsg(GetLastError());
#else
return strerror(error_id);
#endif
return [[[NSError _last] localizedDescription] cString];
}

View file

@ -409,14 +409,30 @@ static NSStringEncoding defaultEncoding;
{
BOOL ok = NO;
#ifdef HAVE_PWD_H
#if defined(HAVE_GETPWNAM_R)
struct passwd pw;
char buf[BUFSIZ*10];
if (getpwnam_r([str cStringUsingEncoding: defaultEncoding],
&pw, buf, sizeof(buf), 0) == 0)
{
ok = (chown(lpath, pw.pw_uid, -1) == 0);
chown(lpath, -1, pw.pw_gid);
}
#else
#if defined(HAVE_GETPWNAM)
struct passwd *pw;
[gnustep_global_lock lock];
pw = getpwnam([str cStringUsingEncoding: defaultEncoding]);
if (pw != 0)
{
ok = (chown(lpath, pw->pw_uid, -1) == 0);
chown(lpath, -1, pw->pw_gid);
}
[gnustep_global_lock unlock];
#endif
#endif
#endif
if (ok == NO)
{
@ -445,14 +461,30 @@ static NSStringEncoding defaultEncoding;
{
BOOL ok = NO;
#ifdef HAVE_GRP_H
#ifdef HAVE_GETGRNAM_R
struct group gp;
char buf[BUFSIZ*10];
if (getgrnam_r([str cStringUsingEncoding: defaultEncoding], &gp,
buf, sizeof(buf), 0) == 0)
{
if (chown(lpath, -1, gp.gr_gid) == 0)
ok = YES;
}
#else
#ifdef HAVE_GETGRNAM
struct group *gp;
[gnustep_global_lock lock];
gp = getgrnam([str cStringUsingEncoding: defaultEncoding]);
if (gp)
{
if (chown(lpath, -1, gp->gr_gid) == 0)
ok = YES;
}
[gnustep_global_lock unlock];
#endif
#endif
#endif
if (ok == NO)
{
@ -2936,14 +2968,29 @@ static NSSet *fileKeys = nil;
return [NSString stringWithCharacters: account length: accountSize];
#else
#if defined(HAVE_GRP_H)
#if defined(HAVE_GETGRGID_H)
struct group gp;
char buf[BUFSIZ*10];
if (getgrgid_r(statbuf.st_gid, &gp, buf, sizeof(buf), 0) == 0)
{
group = [NSString stringWithCString: gp.gr_name
encoding: defaultEncoding];
}
#else
#if defined(HAVE_GETGRGID)
struct group *gp;
[gnustep_global_lock lock];
gp = getgrgid(statbuf.st_gid);
if (gp != 0)
{
group = [NSString stringWithCString: gp->gr_name
encoding: defaultEncoding];
}
[gnustep_global_lock unlock];
#endif
#endif
#endif
#endif
return group;
@ -3077,15 +3124,29 @@ static NSSet *fileKeys = nil;
return [NSString stringWithCharacters: account length: accountSize];
#else
#ifdef HAVE_PWD_H
#if defined(HAVE_GETPWUID_R)
struct passwd pw;
char buf[BUFSIZ*10];
if (getpwuid_r(statbuf.st_uid, &pw, buf, sizeof(buf), 0) == 0)
{
owner = [NSString stringWithCString: pw.pw_name
encoding: defaultEncoding];
}
#else
#if defined(HAVE_GETPWUID)
struct passwd *pw;
[gnustep_global_lock lock];
pw = getpwuid(statbuf.st_uid);
if (pw != 0)
{
owner = [NSString stringWithCString: pw->pw_name
encoding: defaultEncoding];
}
[gnustep_global_lock unlock];
#endif
#endif
#endif /* HAVE_PWD_H */
#endif
return owner;

View file

@ -78,7 +78,7 @@
#include <unistd.h> // for getuid()
#endif
#ifdef HAVE_PWD_H
#include <pwd.h> // for getpwnam()
#include <pwd.h> // for getpwnam_r() and getpwuid_r()
#endif
#include <sys/types.h>
#include <stdio.h>
@ -1265,10 +1265,20 @@ NSUserName(void)
if (theUserName == nil || uid != olduid)
{
const char *loginName = 0;
#ifdef HAVE_GETPWUID
#if defined(HAVE_GETPWUID_R)
struct passwd pwent;
char buf[BUFSIZ*10];
if (getpwuid_r(uid, &pwent, buf, sizeof(buf), 0) == 0)
{
loginName = pwent.pw_name;
}
#else
#if defined(HAVE_GETPWUID)
struct passwd *pwent = getpwuid (uid);
loginName = pwent->pw_name;
#endif /* HAVE_GETPWUID */
#endif /* HAVE_GETPWUID_R */
olduid = uid;
if (loginName)
theUserName = [[NSString alloc] initWithCString: loginName];
@ -1304,6 +1314,17 @@ NSHomeDirectoryForUser(NSString *loginName)
NSString *s = nil;
#if !defined(__MINGW32__)
#if defined(HAVE_GETPWNAM_R)
struct passwd pw;
char buf[BUFSIZ*10];
if (getpwnam_r([loginName cString], &pw, buf, sizeof(buf), 0) == 0
&& pw.pw_dir != 0)
{
s = [NSString stringWithUTF8String: pw.pw_dir];
}
#else
#if defined(HAVE_GETPWNAM)
struct passwd *pw;
[gnustep_global_lock lock];
@ -1313,6 +1334,8 @@ NSHomeDirectoryForUser(NSString *loginName)
s = [NSString stringWithUTF8String: pw->pw_dir];
}
[gnustep_global_lock unlock];
#endif
#endif
#else
if ([loginName isEqual: NSUserName()] == YES)
{
@ -1361,11 +1384,11 @@ NSFullUserName(void)
{
if (theFullUserName == nil)
{
NSString *userName = NSUserName();
NSString *userName = nil;
#if defined(__MINGW32__)
struct _USER_INFO_2 *userInfo;
if (NetUserGetInfo(NULL, (unichar*)[userName cStringUsingEncoding:
if (NetUserGetInfo(NULL, (unichar*)[NSUserName() cStringUsingEncoding:
NSUnicodeStringEncoding], 2, (LPBYTE*)&userInfo) == 0)
{
userName = [NSString stringWithCharacters: userInfo->usri2_full_name
@ -1373,15 +1396,31 @@ NSFullUserName(void)
}
#else
#ifdef HAVE_PWD_H
#if defined(HAVE_GETPWNAM_R)
struct passwd pw;
char buf[BUFSIZ*10];
if (getpwnam_r([NSUserName() cString], &pw, buf, sizeof(buf), 0) == 0)
{
userName = [NSString stringWithUTF8String: pw.pw_gecos];
}
#else
#if defined(HAVE_GETPWNAM)
struct passwd *pw;
[gnustep_global_lock lock];
pw = getpwnam([NSUserName() cString]);
userName = [NSString stringWithUTF8String: pw->pw_gecos];
#else
NSLog(@"Warning: NSFullUserName not implemented\n");
userName = NSUserName();
[gnustep_global_lock lock];
#endif /* HAVE_GETPWNAM */
#endif /* HAVE_GETPWNAM_R */
#endif /* HAVE_PWD_H */
#endif /* defined(__Win32__) else */
if (userName == nil)
{
NSLog(@"Warning: NSFullUserName not implemented\n");
userName = NSUserName();
}
ASSIGN(theFullUserName, userName);
}
return theFullUserName;

View file

@ -780,6 +780,10 @@ static char **_gnu_noobjc_env = NULL;
proc_fs_error:
#ifdef HAVE_STRERROR
/* Don't care about thread safety of strerror() here as this is only
* called in the initial thread and there shouldn't be any other
* threads at this point.
*/
fprintf(stderr, "Couldn't open file %s when starting gnustep-base; %s\n",
proc_file_name, strerror(errno));
#else /* !HAVE_FUNCTION_STRERROR */

View file

@ -38,12 +38,6 @@
*/
/* Global lock to be used by classes when operating on any global
data that invoke other methods which also access global; thus,
creating the potential for deadlock. */
@class NSRecursiveLock;
NSRecursiveLock *gnustep_global_lock = nil;
/*
* NSConnection Notification Strings.
*/

View file

@ -593,8 +593,7 @@ main(int argc, char** argv, char **env)
if ([defs synchronize] == NO)
{
GSPrintf(stderr,
@"defaults: unable to write to defaults database - %s\n",
strerror(errno));
@"defaults: unable to write to defaults database\n");
}
}
else if ([[args objectAtIndex: i] isEqual: @"delete"])
@ -718,8 +717,7 @@ main(int argc, char** argv, char **env)
if ([defs synchronize] == NO)
{
GSPrintf(stderr,
@"defaults: unable to write to defaults database - %s\n",
strerror(errno));
@"defaults: unable to write to defaults database\n");
}
}
else if ([[args objectAtIndex: i] isEqual: @"domains"])

13709
configure vendored

File diff suppressed because it is too large Load diff

View file

@ -1340,7 +1340,7 @@ AC_CHECK_HEADERS([sys/mount.h], [], [],
AC_CHECK_HEADERS(sys/types.h windows.h locale.h langinfo.h)
saved_LIBS="$LIBS"
AC_CHECK_LIB(m, main)
AC_CHECK_FUNCS(statvfs link symlink readlink geteuid getlogin getpwnam getpwuid getgrgid rint getopt)
AC_CHECK_FUNCS(statvfs link symlink readlink geteuid getlogin getpwnam getpwnam_r getpwuid getpwuid_r getgrgid getgrgid_r getgrnam getgrnam_r rint getopt)
LIBS="$saved_LIBS"
#--------------------------------------------------------------------
@ -1527,7 +1527,7 @@ AC_SUBST(DEFINE_UINTPTR_T)
#--------------------------------------------------------------------
# These used by GSFileHandle.m and distributed objects
#--------------------------------------------------------------------
AC_CHECK_FUNCS(inet_aton inet_pton sigaction)
AC_CHECK_FUNCS(gethostbyaddr_r inet_aton inet_pton inet_ntop sigaction)
USE_ZLIB=0
AC_CHECK_HEADERS(zlib.h)
if test $ac_cv_header_zlib_h = yes; then
@ -1551,9 +1551,9 @@ AC_SUBST(HAVE_INET_PTON)
AC_CHECK_FUNCS(nanosleep usleep)
#--------------------------------------------------------------------
# This function needed by NSDebug.m and NSProcessInfo.m
# One of these functions needed by NSDebug.m and NSProcessInfo.m
#--------------------------------------------------------------------
AC_CHECK_FUNCS(strerror)
AC_CHECK_FUNCS(strerror_r strerror)
#--------------------------------------------------------------------
# This type needed by GSFormat