Clean up the port considerably, and fix several serious bugs. There are

still some problems, at least with signal handling and locking on SMP.

Submitted by:	dick
This commit is contained in:
Jason Evans 2000-01-04 00:05:24 +00:00
parent d031962a9f
commit 1c274b738e
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=24399
10 changed files with 1029 additions and 825 deletions

View file

@ -0,0 +1,100 @@
#include <poll.h>
#include <bits/local_lim.h>
#include <sys/queue.h>
#define __libc_close _close
#define __libc_nanosleep _nanosleep
#define __libc_read _read
#define __libc_waitpid waitpid
#define __libc_write _write
#define __libc_longjmp __longjmp
#define __libc_siglongjmp __siglongjmp
#define __libc_fork _fork
#define __libc_current_sigrtmin current_sigrtmin
#define __libc_current_sigrtmax current_sigrtmax
#define __libc_allocate_rtsig allocate_rtsig
#define __getpagesize getpagesize
#define __sched_param sched_param
#define __sched_get_priority_min sched_get_priority_min
#define __sched_get_priority_max sched_get_priority_max
#define __sched_setscheduler sched_setscheduler
#define __sched_getscheduler sched_getscheduler
#define __sched_getparam sched_getparam
#define __gettimeofday _gettimeofday
#define __poll _poll
#define __getpid _getpid
#define __jmp_buf jmp_buf
#define __sigaction _sigaction
#define _errno errno
#define _h_errno h_errno
#ifndef __P
# define __P(args) args
#endif
#ifndef __PMT
# define __PMT(args) args
#endif
# define strong_alias(name, aliasname) \
extern __typeof (name) aliasname __attribute__ ((alias (#name)));
# define weak_alias(name, aliasname) \
extern __typeof (name) aliasname __attribute__ ((weak, alias (#name)));
#define ENOTSUP EOPNOTSUPP
#define __builtin_expect(x,y) (x) == (y)
#define internal_function
#undef PAGE_SIZE
#define PAGE_SIZE getpagesize()
#define MAP_ANONYMOUS MAP_ANON
#define MAP_GROWSDOWN MAP_STACK
#define __WCLONE WLINUXCLONE
#define SIGCONTEXT struct sigcontext *
#define SIGCONTEXT_EXTRA_ARGS
# define __WAIT_STATUS_DEFN int *
# define __SOCKADDR_ARG struct sockaddr *
# define __CONST_SOCKADDR_ARG __const struct sockaddr *
#define __ptr_t void *
#define __pid_t pid_t
/* Test if longjmp to JMPBUF would unwind the frame
containing a local variable at ADDRESS. */
/* XXXX check this for FreeBSD */
/* i386 only */
#define JB_SP 2
#define _JMPBUF_UNWINDS(jmpbuf, address) \
((void *) (address) < (void *) ((int *)(jmpbuf[0]._jb[JB_SP]))[1])
#define spinlock_t int
#define _SPINLOCK_INITIALIZER 0
#define _SPINLOCK(x) __pthread_acquire(x)
#define _SPINUNLOCK(x) *(x) = 0
/*#define TEST_FOR_COMPARE_AND_SWAP*/
#define __set_errno(val) errno = (val)
#define DEFAULT_PRIORITY 20
void __libc_longjmp __P((jmp_buf, int)) __dead2;
void __libc_siglongjmp __P((sigjmp_buf, int)) __dead2;
int _gettimeofday __P((struct timeval *, struct timezone *));
pid_t _getpid __P((void));
int _sigaction __P((int, const struct sigaction *, struct sigaction *));
int _poll __P((struct pollfd *_pfd, unsigned _nfds, int _timeout));
#include "clone.h"

View file

@ -0,0 +1,165 @@
#include "pthread.h"
#include <netdb.h>
#include <string.h>
#ifdef __sparc__
#define NEED_ALIGNED_ACCESS
#endif
static pthread_mutex_t gethostby_mutex = PTHREAD_MUTEX_INITIALIZER;
static int
convert (struct hostent *host, struct hostent *result,
char *buf, int buflen, int *h_errnop)
{
int len, i;
if (!buf || !h_errnop) return -1;
*h_errnop = h_errno;
*result = *host;
result->h_name = (char *) buf;
/* This is the size. */
len = strlen (host->h_name) + 1;
if (len > buflen) return -1;
buflen -= len;
buf += len;
strcpy ((char *) result->h_name, host->h_name);
/* How many aliases and how big the buffer should be? There
is always a NULL pointer. */
for (len = sizeof (char *), i = 0; host->h_aliases [i]; i++)
{
/* It should be size of (char *) and the length of string
plus 1. */
len += strlen (host->h_aliases [i]) + 1 + sizeof (char *);
}
if (len > buflen) return -1;
buflen -= len;
/* This is an array of char * for h_aliases. */
#ifdef NEED_ALIGNED_ACCESS
{
int extra;
extra = 4 - (((unsigned long) buf) & 3);
if (extra != 4) {
if (buflen < extra)
return -1;
buf = (char *) buf + extra;
}
}
#endif
result->h_aliases = (char **) buf;
buf += (i + 1) * sizeof (char *);
/* We copy the aliases now. */
for (i = 0; host->h_aliases [i]; i++)
{
result->h_aliases [i] = (char *) buf;
strcpy (result->h_aliases [i], host->h_aliases [i]);
buf += strlen (host->h_aliases [i]) + 1;
}
/* This is the last one */
result->h_aliases [i] = NULL;
#if BSD >= 43 || defined(h_addr)
for (len = sizeof (char *), i = 0; host->h_addr_list [i]; i++)
{
/* It should be size of (char *) and the length of string
plus 1. */
len += host->h_length + sizeof (char *);
}
if (len > buflen) return -1;
/* This is an array of char * for h_addr_list. */
#ifdef NEED_ALIGNED_ACCESS
{
int extra;
extra = 4 - (((unsigned long) buf) & 0x3);
if (extra != 4) {
if (buflen < extra)
return -1;
buf = ((char *) buf) + extra;
}
}
#endif
result->h_addr_list = (char **) buf;
buf += (i + 1) * sizeof (char *);
/* We copy the h_addr_list now. */
for (i = 0; host->h_addr_list [i]; i++)
{
result->h_addr_list [i] = (char *) buf;
memcpy (result->h_addr_list [i], host->h_addr_list [i], host->h_length);
buf += host->h_length;
}
/* This is the last one */
result->h_addr_list [i] = NULL;
#else
len = strlen (host->h_addr) + 1 + sizeof (char *);
if (len > buflen) return -1;
result->h_addr = (char *) buf;
strcpy (result->h_addr, host->h_addr);
#endif
return 0;
}
struct hostent *
gethostbyaddr_r (const char *addr, int length, int type,
struct hostent *result, char *buffer, int buflen,
int *h_errnop)
{
struct hostent *host;
pthread_mutex_lock (&gethostby_mutex);
host = gethostbyaddr (addr, length, type);
if (!host ||
convert (host, result, buffer, buflen, h_errnop) != 0)
{
result = NULL;
}
pthread_mutex_unlock (&gethostby_mutex);
return result;
}
struct hostent *
gethostbyname_r (const char *name,
struct hostent *result, char *buffer, int buflen,
int *h_errnop)
{
struct hostent *host;
pthread_mutex_lock (&gethostby_mutex);
host = gethostbyname (name);
if (!host ||
convert (host, result, buffer, buflen, h_errnop) != 0)
{
result = NULL;
}
pthread_mutex_unlock (&gethostby_mutex);
return result;
}
struct hostent *
gethostent_r (struct hostent *result, char *buffer, int buflen,
int *h_errnop)
{
struct hostent *host;
pthread_mutex_lock (&gethostby_mutex);
host = gethostent ();
if (!host ||
convert (host, result, buffer, buflen, h_errnop) != 0)
{
result = NULL;
}
pthread_mutex_unlock (&gethostby_mutex);
return result;
}

View file

@ -0,0 +1,105 @@
#include "pthread.h"
#include <netdb.h>
#include <string.h>
static pthread_mutex_t getnetby_mutex = PTHREAD_MUTEX_INITIALIZER;
static int
convert (struct netent *ret, struct netent *result,
char *buf, int buflen)
{
int len, i;
if (!buf) return -1;
*result = *ret;
result->n_name = (char *) buf;
/* This is the size. */
len = strlen (ret->n_name) + 1;
if (len > buflen) return -1;
buflen -= len;
buf += len;
strcpy (result->n_name, ret->n_name);
/* How many aliases and how big the buffer should be? There
is always a NULL pointer. */
for (len = sizeof (char *), i = 0; ret->n_aliases [i]; i++)
{
/* It should be size of (char *) and the length of string
plus 1. */
len += strlen (ret->n_aliases [i]) + 1 + sizeof (char *);
}
if (len > buflen) return -1;
/* This is an array of char * for n_aliases. */
result->n_aliases = (char **) buf;
buf += (i + 1) * sizeof (char *);
/* We copy the aliases now. */
for (i = 0; ret->n_aliases [i]; i++)
{
result->n_aliases [i] = (char *) buf;
strcpy (result->n_aliases [i], ret->n_aliases [i]);
buf += strlen (ret->n_aliases [i]) + 1;
}
/* This is the last one */
result->n_aliases [i] = NULL;
return 0;
}
struct netent *
getnetbyaddr_r (long net, int type,
struct netent *result, char *buffer, int buflen)
{
struct netent *ret;
pthread_mutex_lock (&getnetby_mutex);
ret = getnetbyaddr (net, type);
if (!ret ||
convert (ret, result, buffer, buflen) != 0)
{
result = NULL;
}
pthread_mutex_unlock (&getnetby_mutex);
return result;
}
struct netent *
getnetbyname_r (const char *name,
struct netent *result, char *buffer, int buflen)
{
struct netent *ret;
pthread_mutex_lock (&getnetby_mutex);
ret = getnetbyname (name);
if (!ret ||
convert (ret, result, buffer, buflen) != 0)
{
result = NULL;
}
pthread_mutex_unlock (&getnetby_mutex);
return result;
}
struct netent *
getnetent_r (struct netent *result, char *buffer, int buflen)
{
struct netent *ret;
pthread_mutex_lock (&getnetby_mutex);
ret = getnetent ();
if (!ret ||
convert (ret, result, buffer, buflen) != 0)
{
result = NULL;
}
pthread_mutex_unlock (&getnetby_mutex);
return result;
}

View file

@ -0,0 +1,105 @@
#include "pthread.h"
#include <netdb.h>
#include <string.h>
static pthread_mutex_t getprotoby_mutex = PTHREAD_MUTEX_INITIALIZER;
static int
convert (struct protoent *ret, struct protoent *result,
char *buf, int buflen)
{
int len, i;
if (!buf) return -1;
*result = *ret;
result->p_name = (char *) buf;
/* This is the size. */
len = strlen (ret->p_name) + 1;
if (len > buflen) return -1;
buflen -= len;
buf += len;
strcpy (result->p_name, ret->p_name);
/* How many aliases and how big the buffer should be? There
is always a NULL pointer. */
for (len = sizeof (char *), i = 0; ret->p_aliases [i]; i++)
{
/* It should be size of (char *) and the length of string
plus 1. */
len += strlen (ret->p_aliases [i]) + 1 + sizeof (char *);
}
if (len > buflen) return -1;
/* This is an array of char * for p_aliases. */
result->p_aliases = (char **) buf;
buf += (i + 1) * sizeof (char *);
/* We copy the aliases now. */
for (i = 0; ret->p_aliases [i]; i++)
{
result->p_aliases [i] = (char *) buf;
strcpy (result->p_aliases [i], ret->p_aliases [i]);
buf += strlen (ret->p_aliases [i]) + 1;
}
/* This is the last one */
result->p_aliases [i] = NULL;
return 0;
}
struct protoent *
getprotobynumber_r (int proto,
struct protoent *result, char *buffer, int buflen)
{
struct protoent *ret;
pthread_mutex_lock (&getprotoby_mutex);
ret = getprotobynumber (proto);
if (!ret ||
convert (ret, result, buffer, buflen) != 0)
{
result = NULL;
}
pthread_mutex_unlock (&getprotoby_mutex);
return result;
}
struct protoent *
getprotobyname_r (const char *name,
struct protoent *result, char *buffer, int buflen)
{
struct protoent *ret;
pthread_mutex_lock (&getprotoby_mutex);
ret = getprotobyname (name);
if (!ret ||
convert (ret, result, buffer, buflen) != 0)
{
result = NULL;
}
pthread_mutex_unlock (&getprotoby_mutex);
return result;
}
struct protoent *
getprotoent_r (struct protoent *result, char *buffer, int buflen)
{
struct protoent *ret;
pthread_mutex_lock (&getprotoby_mutex);
ret = getprotoent ();
if (!ret ||
convert (ret, result, buffer, buflen) != 0)
{
result = NULL;
}
pthread_mutex_unlock (&getprotoby_mutex);
return result;
}

View file

@ -0,0 +1,108 @@
#include <stddef.h>
#include <string.h>
#include <errno.h>
#include <pwd.h>
#include "pthread.h"
static pthread_mutex_t getpw_mutex = PTHREAD_MUTEX_INITIALIZER;
static int
convert (struct passwd *ret, struct passwd *result,
char *buf, int buflen)
{
int len;
if (!buf) return -1;
*result = *ret;
result->pw_name = (char *) buf;
/* This is the size. */
len = strlen (ret->pw_name) + 1;
if (len > buflen) return -1;
buflen -= len;
buf += len;
strcpy (result->pw_name, ret->pw_name);
result->pw_passwd = (char *) buf;
/* This is the size. */
len = strlen (ret->pw_passwd) + 1;
if (len > buflen) return -1;
buflen -= len;
buf += len;
strcpy (result->pw_passwd, ret->pw_passwd);
result->pw_gecos = (char *) buf;
/* This is the size. */
len = strlen (ret->pw_gecos) + 1;
if (len > buflen) return -1;
buflen -= len;
buf += len;
strcpy (result->pw_gecos, ret->pw_gecos);
result->pw_dir = (char *) buf;
/* This is the size. */
len = strlen (ret->pw_dir) + 1;
if (len > buflen) return -1;
buflen -= len;
buf += len;
strcpy (result->pw_dir, ret->pw_dir);
result->pw_shell = (char *) buf;
/* This is the size. */
len = strlen (ret->pw_shell) + 1;
if (len > buflen) return -1;
buflen -= len;
buf += len;
strcpy (result->pw_shell, ret->pw_shell);
return 0;
}
int getpwnam_r (const char *name, struct passwd *result,
char *buffer, size_t buflen,
struct passwd ** resptr)
{
struct passwd * p;
int retval;
pthread_mutex_lock (&getpw_mutex);
p = getpwnam (name);
if (p == NULL) {
*resptr = NULL;
retval = ESRCH;
} else
if (convert (p, result, buffer, buflen) != 0) {
*resptr = NULL;
retval = ERANGE;
} else {
*resptr = result;
retval = 0;
}
pthread_mutex_unlock (&getpw_mutex);
return retval;
}
int getpwuid_r (uid_t uid, struct passwd *result,
char *buffer, size_t buflen,
struct passwd ** resptr)
{
struct passwd * p;
int retval;
pthread_mutex_lock (&getpw_mutex);
p = getpwuid (uid);
if (p == NULL) {
*resptr = NULL;
retval = ESRCH;
} else
if (convert (p, result, buffer, buflen) != 0) {
*resptr = NULL;
retval = ERANGE;
} else {
*resptr = result;
retval = 0;
}
pthread_mutex_unlock (&getpw_mutex);
return retval;
}

View file

@ -0,0 +1,113 @@
#include "pthread.h"
#include <netdb.h>
#include <string.h>
static pthread_mutex_t getservby_mutex = PTHREAD_MUTEX_INITIALIZER;
static int
convert (struct servent *ret, struct servent *result,
char *buf, int buflen)
{
int len, i;
if (!buf) return -1;
*result = *ret;
/* This is the size. */
len = strlen (ret->s_name) + 1;
if (len > buflen) return -1;
buflen -= len;
result->s_name = (char *) buf;
buf += len;
strcpy (result->s_name, ret->s_name);
/* How many aliases and how big the buffer should be? There
is always a NULL pointer. */
for (len = sizeof (char *), i = 0; ret->s_aliases [i]; i++)
{
/* It should be size of (char *) and the length of string
plus 1. */
len += strlen (ret->s_aliases [i]) + 1 + sizeof (char *);
}
if (len > buflen) return -1;
buflen -= len;
/* This is an array of char * for s_aliases. */
result->s_aliases = (char **) buf;
buf += (i + 1) * sizeof (char *);
/* We copy the aliases now. */
for (i = 0; ret->s_aliases [i]; i++)
{
result->s_aliases [i] = (char *) buf;
strcpy (result->s_aliases [i], ret->s_aliases [i]);
buf += strlen (ret->s_aliases [i]) + 1;
}
/* This is the last one */
result->s_aliases [i] = NULL;
/* s_proto */
len = strlen (ret->s_proto) + 1;
if (len > buflen) return -1;
buf += len;
result->s_proto = (char *) buf;
strcpy (result->s_proto, ret->s_proto);
return 0;
}
struct servent *
getservbyport_r (int port, const char *proto,
struct servent *result, char *buffer, int buflen)
{
struct servent *ret;
pthread_mutex_lock (&getservby_mutex);
ret = getservbyport (port, proto);
if (!ret ||
convert (ret, result, buffer, buflen) != 0)
{
result = NULL;
}
pthread_mutex_unlock (&getservby_mutex);
return result;
}
struct servent *
getservbyname_r (const char *name, const char *proto,
struct servent *result, char *buffer, int buflen)
{
struct servent *ret;
pthread_mutex_lock (&getservby_mutex);
ret = getservbyname (name, proto);
if (!ret ||
convert (ret, result, buffer, buflen) != 0)
{
result = NULL;
}
pthread_mutex_unlock (&getservby_mutex);
return result;
}
struct servent *
getservent_r (struct servent *result, char *buffer, int buflen)
{
struct servent *ret;
pthread_mutex_lock (&getservby_mutex);
ret = getservent ();
if (!ret ||
convert (ret, result, buffer, buflen) != 0)
{
result = NULL;
}
pthread_mutex_unlock (&getservby_mutex);
return result;
}

View file

@ -72,7 +72,7 @@ extern int __clone __P ((int (*__fn) (void *), void *__child_stack,
* to do anything special in this case.
*/
break;
case SIGUSR2:
case SIGUSR1:
bsd_flags |= RFLINUXTHPN;
break;
default:

View file

@ -35,19 +35,22 @@
#define _THREAD_SAFE
#endif
#include <dlfcn.h>
#include <stdlib.h>
#include "pthread.h"
/* Our internal pthreads definitions are here. Set as needed */
#if defined(COMPILING_UTHREADS)
#include "pthread_private.h"
#endif
#if defined(LINUXTHREADS)
#include <errno.h>
#include "internals.h"
#include "spinlock.h"
#else
/* Your internal definition here */
#endif
/* These are from lib/libc/include */
#include "libc_private.h"
#if !defined(LINUXTHREADS)
#include "spinlock.h"
#endif
@ -97,11 +100,19 @@ extern pthread_mutex_t *localtime_mutex;
extern pthread_mutex_t *gmtime_mutex;
#endif
void *lock_create (void *context);
void rlock_acquire (void *lock);
void wlock_acquire (void *lock);
void lock_release (void *lock);
void lock_destroy (void *lock);
/* Use the constructor attribute so this gets run before main does */
static void _pthread_initialize(void) __attribute__((constructor));
static void _pthread_initialize(void)
{
#if defined(LINUXTHREADS)
int mib[2];
size_t len;
@ -116,6 +127,14 @@ static void _pthread_initialize(void)
/* This turns on thread safe behaviour in libc when we link with it */
__isthreaded = 1;
dllockinit (NULL,
lock_create,
rlock_acquire,
wlock_acquire,
lock_release,
lock_destroy,
NULL);
#if defined(NEWLIBC)
/* Set up pointers for lib/libc/stdtime/localtime.c */
lcl_mutex = &_lcl_mutex;
@ -125,3 +144,42 @@ static void _pthread_initialize(void)
#endif
}
void _spinlock (int * spinlock)
{
__pthread_acquire(spinlock);
}
void * lock_create (void *context)
{
pthread_rwlock_t *lock;
lock = malloc (sizeof (*lock));
if (lock == NULL)
return (NULL);
pthread_rwlock_init (lock, NULL);
return (lock);
}
void rlock_acquire (void *lock)
{
pthread_rwlock_rdlock ((pthread_rwlock_t *)lock);
}
void wlock_acquire (void *lock)
{
pthread_rwlock_wrlock ((pthread_rwlock_t *)lock);
}
void lock_release (void *lock)
{
pthread_rwlock_unlock ((pthread_rwlock_t *)lock);
}
void lock_destroy (void *lock)
{
if (pthread_rwlock_destroy ((pthread_rwlock_t *)lock) == 0)
free (lock);
}

File diff suppressed because it is too large Load diff

View file

@ -36,13 +36,14 @@
* level too.
*
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pthread.h"
#include "internals.h"
#include "spinlock.h"
#include "restart.h"
#include "libc_spinlock.h"
/*
* Weak symbols for externally visible functions in this file: