This is a patch to the MIT pthreads package version 1.60 beta2 for Linux 1.2.x
systems with the ELF object format.  It is known to work for at least 1.2.4 
with libc 5.0.2.  

To get shared libraries, add -fPIC to the CFLAGS in GNUmakefile and the 
following lines:

obj/libpthread.so.1.60: ${REALOBJS}
	cd obj && \
		${CC} -shared -o libpthread.so.1.60 ${CFLAGS} ${OBJS} &&\
		cd ..

and change the all-lib line to:

all-lib : libpthread.a obj/libpthread.so.1.60

Questions about pthreads to pthreads@mit.edu, about this patch to hhc@mit.edu.
=======
diff -r -C 2 pthreads-1_60_beta2/include/arpa/nameser.h pthreads/include/arpa/nameser.h
*** pthreads-1_60_beta2/include/arpa/nameser.h	Fri Feb 24 00:37:00 1995
--- pthreads/include/arpa/nameser.h	Tue Apr 25 23:51:04 1995
***************
*** 60,63 ****
--- 60,67 ----
  #include <pthread/types.h>
  
+ #ifdef __linux__
+ #include <endian.h>
+ #endif
+ 
  /*
   * Define constants based on rfc883
diff -r -C 2 pthreads-1_60_beta2/include/pthread.h pthreads/include/pthread.h
*** pthreads-1_60_beta2/include/pthread.h	Sun Mar 26 02:44:25 1995
--- pthreads/include/pthread.h	Fri Apr 28 20:21:11 1995
***************
*** 247,250 ****
--- 247,254 ----
  											 struct sched_param * param));
  
+ int 	pthread_kill 	__P((struct pthread * pthread, int sig));
+ int	pthread_signal	__P((int sig, void (*dispatch)(int)));
+ 
+ 
  #endif
  
diff -r -C 2 pthreads-1_60_beta2/include/signal.h pthreads/include/signal.h
*** pthreads-1_60_beta2/include/signal.h	Fri Feb 24 00:36:01 1995
--- pthreads/include/signal.h	Tue May  2 01:57:13 1995
***************
*** 44,47 ****
--- 44,50 ----
  
  int	raise 			__P((int));
+ #ifdef linux
+ extern __const char * __const sys_siglist[];
+ #endif
  
  #ifndef	_ANSI_SOURCE
diff -r -C 2 pthreads-1_60_beta2/include/stdlib.h pthreads/include/stdlib.h
*** pthreads-1_60_beta2/include/stdlib.h	Tue Feb 28 20:06:10 1995
--- pthreads/include/stdlib.h	Fri Apr 28 23:53:28 1995
***************
*** 104,108 ****
  
  void		  * bsearch		__P((const void *, const void *, size_t, size_t,
! 							void (* __func)() ));
  void		   	qsort		__P((void *, size_t, size_t, 
  							int (* __func)__P((const void *, const void *)) ));
--- 104,108 ----
  
  void		  * bsearch		__P((const void *, const void *, size_t, size_t,
! 							int (* __func)__P((const void *, const void *)) ));
  void		   	qsort		__P((void *, size_t, size_t, 
  							int (* __func)__P((const void *, const void *)) ));
diff -r -C 2 pthreads-1_60_beta2/machdep/engine-i386-linux-1.0.c pthreads/machdep/engine-i386-linux-1.0.c
*** pthreads-1_60_beta2/machdep/engine-i386-linux-1.0.c	Wed Mar 29 13:01:46 1995
--- pthreads/machdep/engine-i386-linux-1.0.c	Tue May 23 05:15:27 1995
***************
*** 20,23 ****
--- 20,25 ----
  #include <sys/socketcall.h>
  
+ #include <alloca.h>
+ 
  /* ==========================================================================
   * machdep_save_state()
***************
*** 215,219 ****
      array[1] = (int)b;
  
!     return(machdep_sys_socketcall(SYS_GETSOCKOPT, array));
  }
  
--- 217,222 ----
      array[1] = (int)b;
  
! /*    return(machdep_sys_socketcall(SYS_GETSOCKOPT, array)); */
!     return(machdep_sys_socketcall(SYS_SHUTDOWN, array));
  }
  
***************
*** 332,339 ****
  /* ==========================================================================
   * machdep_sys_readv()
   */
! int machdep_sys_readv(int a, struct iovec * b, int c)
  {
! 	return(-ENOSYS);
  }
  
--- 335,382 ----
  /* ==========================================================================
   * machdep_sys_readv()
+  * 
+  * taken from the GNU C Library posix/readv.c
   */
! int machdep_sys_readv(int fd, struct iovec * vector, int count)
  {
!   char *buffer;
!   size_t bytes;
!   int bytes_read;
!   register size_t i;
! 
!   /* Find the total number of bytes to be read.  */
!   bytes = 0;
!   for (i = 0; i < count; ++i)
!     bytes += vector[i].iov_len;
! 
!   /* Allocate a temporary buffer to hold the data.  */
!   buffer = (char *) __alloca(bytes);
! 
!   /* Read the data.  */
!   bytes_read = machdep_sys_read(fd, buffer, bytes);
!   if (bytes_read < 0)
!     return -1;
! 
!   if (bytes_read == 0)
!     return 0;
! 
!   /* Copy the data from BUFFER into the memory specified by VECTOR.  */
!   bytes = bytes_read;
!   for (i = 0; i < count; ++i)
!     {
! /*
! #define	min(a, b)	((a) > (b) ? (b) : (a))
! */
!       size_t copy = min(vector[i].iov_len, bytes);
! 
!       (void) memcpy((void *) vector[i].iov_base, (void *) buffer, copy);
! 
!       buffer += copy;
!       bytes -= copy;
!       if (bytes == 0)
! 	break;
!     }
! 
!   return bytes_read;
  }
  
***************
*** 348,355 ****
  /* ==========================================================================
   * machdep_sys_writev()
   */
! int machdep_sys_writev(int a, struct iovec * b, int c)
  {
! 	return(-ENOSYS);
  }
  
--- 391,434 ----
  /* ==========================================================================
   * machdep_sys_writev()
+  * 
+  * taken from the GNU C Library posix/writev.c
   */
! int machdep_sys_writev(int fd, struct iovec * vector, int count)
  {
!   char *buffer;
!   register char *bp;
!   size_t bytes, to_copy;
!   register size_t i;
! 
!   /* Find the total number of bytes to be written.  */
!   bytes = 0;
!   for (i = 0; i < count; ++i)
!     bytes += vector[i].iov_len;
! 
!   if (bytes == 0)
!     return 0;
! 
!   /* Allocate a temporary buffer to hold the data.  */
!   buffer = (char *) __alloca(bytes);
! 
!   /* Copy the data into BUFFER.  */
!   to_copy = bytes;
!   bp = buffer;
!   for (i = 0; i < count; ++i)
!     {
! /* defined above in readv already
!  #define	min(a, b)	((a) > (b) ? (b) : (a))
! */
!       size_t copy = min(vector[i].iov_len, to_copy);
! 
!       (void) memcpy((void *) bp, (void *) vector[i].iov_base, copy);
! 
!       bp += copy;
!       to_copy -= copy;
!       if (bytes == 0)
! 	break;
!     }
! 
!   return machdep_sys_write(fd, buffer, bytes);
  }
  
***************
*** 370,374 ****
  
  	if ((ret = machdep_sys_readdir(fd, buf, 1)) >= OK) {
! 		return 1;
  	}
  	return(ret);
--- 449,453 ----
  
  	if ((ret = machdep_sys_readdir(fd, buf, 1)) >= OK) {
! 		return (ret == 0) ? 0 : 1;
  	}
  	return(ret);
diff -r -C 2 pthreads-1_60_beta2/machdep/linux-1.0/__signal.h pthreads/machdep/linux-1.0/__signal.h
*** pthreads-1_60_beta2/machdep/linux-1.0/__signal.h	Tue Feb 28 20:28:06 1995
--- pthreads/machdep/linux-1.0/__signal.h	Thu Apr 27 00:29:08 1995
***************
*** 20,21 ****
--- 20,24 ----
  #define	__SIGISMEMBER(s,n)	((*s) & (1 << ((n) - 1))) 
  
+ #define __sigmask(sig)	(1 << ((sig) - 1))
+ #define sigmask           __sigmask
+ 
diff -r -C 2 pthreads-1_60_beta2/machdep/linux-1.0/cdefs.h pthreads/machdep/linux-1.0/cdefs.h
*** pthreads-1_60_beta2/machdep/linux-1.0/cdefs.h	Mon Apr  3 22:43:23 1995
--- pthreads/machdep/linux-1.0/cdefs.h	Tue Apr 25 23:40:41 1995
***************
*** 1,5 ****
  #ifndef _PTHREAD_SYS_CDEFS_H_
  #define _PTHREAD_SYS_CDEFS_H_
- #include_next <sys/cdefs.h>
  
  #ifndef __NORETURN
--- 1,5 ----
+ #include_next <sys/cdefs.h>
  #ifndef _PTHREAD_SYS_CDEFS_H_
  #define _PTHREAD_SYS_CDEFS_H_
  
  #ifndef __NORETURN
diff -r -C 2 pthreads-1_60_beta2/machdep/linux-1.0/dirent.h pthreads/machdep/linux-1.0/dirent.h
*** pthreads-1_60_beta2/machdep/linux-1.0/dirent.h	Sun Aug  7 23:43:50 1994
--- pthreads/machdep/linux-1.0/dirent.h	Thu Apr 27 17:42:47 1995
***************
*** 3,6 ****
--- 3,7 ----
  #define _SYS_DIRENT_H
  
+ #include <sys/types.h>
  #include <linux/limits.h>
  
diff -r -C 2 pthreads-1_60_beta2/machdep/linux-1.0/wait.h pthreads/machdep/linux-1.0/wait.h
*** pthreads-1_60_beta2/machdep/linux-1.0/wait.h	Fri Sep 16 00:37:03 1994
--- pthreads/machdep/linux-1.0/wait.h	Thu Apr 27 17:17:06 1995
***************
*** 48,52 ****
  #define	__WSTATUS(x)		(__W_INT(x) & 0177)
  #define	__WSTOPPED			0177		/* __WSTATUS if process is stopped */
! #define WIFSTOPPED(x)		(_WSTATUS(x) == __WSTOPPED)
  #define WSTOPSIG(x)			(__W_INT(x) >> 8)
  #define WIFSIGNALED(x)		(__WSTATUS(x) != __WSTOPPED && __WSTATUS(x) != 0)
--- 48,52 ----
  #define	__WSTATUS(x)		(__W_INT(x) & 0177)
  #define	__WSTOPPED			0177		/* __WSTATUS if process is stopped */
! #define WIFSTOPPED(x)		(__WSTATUS(x) == __WSTOPPED)
  #define WSTOPSIG(x)			(__W_INT(x) >> 8)
  #define WIFSIGNALED(x)		(__WSTATUS(x) != __WSTOPPED && __WSTATUS(x) != 0)
diff -r -C 2 pthreads-1_60_beta2/machdep/syscall-i386-linux-1.0.S pthreads/machdep/syscall-i386-linux-1.0.S
*** pthreads-1_60_beta2/machdep/syscall-i386-linux-1.0.S	Tue Feb 28 20:21:36 1995
--- pthreads/machdep/syscall-i386-linux-1.0.S	Fri Apr 28 21:51:36 1995
***************
*** 27,42 ****
  
  #define SYSCALL0(x)					\
! 	.globl _machdep_sys_##x;		\
  									\
! _machdep_sys_##x##:;				\
  									\
  	lea	SYS_##x, %eax;				\
  	int $0x80;						\
! 	ret;
  
  #define SYSCALL1(x)					\
! 	.globl _machdep_sys_##x;		\
  									\
! _machdep_sys_##x##:;				\
  									\
  	push %ebx;						\
--- 27,47 ----
  
  #define SYSCALL0(x)					\
! 	.globl machdep_sys_##x;		\
  									\
! machdep_sys_##x##:;				\
  									\
+ 	push %ebx;						\
  	lea	SYS_##x, %eax;				\
  	int $0x80;						\
! 	pop %ebx;						\
! 	ret;                                                    \
! 	.type machdep_sys_##x, @function; \
! .L_machdep_sys_##x##_end:; \
! 	.size machdep_sys_##x,.L_machdep_sys_##x##_end - machdep_sys_##x;
  
  #define SYSCALL1(x)					\
! 	.globl machdep_sys_##x;		\
  									\
! machdep_sys_##x##:;				\
  									\
  	push %ebx;						\
***************
*** 45,54 ****
  	int $0x80;						\
  	pop %ebx;						\
! 	ret;
  
  #define SYSCALL2(x)					\
! 	.globl _machdep_sys_##x;		\
  									\
! _machdep_sys_##x##:;				\
  									\
  	push %ebx;						\
--- 50,62 ----
  	int $0x80;						\
  	pop %ebx;						\
! 	ret; \
! 	.type machdep_sys_##x, @function; \
! .L_machdep_sys_##x##_end:; \
! 	.size machdep_sys_##x,.L_machdep_sys_##x##_end - machdep_sys_##x;
  
  #define SYSCALL2(x)					\
! 	.globl machdep_sys_##x;		\
  									\
! machdep_sys_##x##:;				\
  									\
  	push %ebx;						\
***************
*** 58,67 ****
  	int $0x80;						\
  	pop %ebx;						\
! 	ret;
  
  #define SYSCALL3(x)					\
! 	.globl _machdep_sys_##x;		\
  									\
! _machdep_sys_##x##:;				\
  									\
  	push %ebx;						\
--- 66,94 ----
  	int $0x80;						\
  	pop %ebx;						\
! 	ret; \
! 	.type machdep_sys_##x, @function; \
! .L_machdep_sys_##x##_end:; \
! 	.size machdep_sys_##x,.L_machdep_sys_##x##_end - machdep_sys_##x;
! 
! #define STATCALL2(x)					\
! 	.globl machdep_sys_##x;		\
! 									\
! machdep_sys_##x##:;				\
! 									\
! 	push %ebx;						\
! 	mov 8(%esp), %ebx;				\
! 	mov 12(%esp), %ecx;				\
! 	lea	SYS_prev_##x, %eax;				\
! 	int $0x80;						\
! 	pop %ebx;						\
! 	ret; \
! 	.type machdep_sys_##x, @function; \
! .L_machdep_sys_##x##_end:; \
! 	.size machdep_sys_##x,.L_machdep_sys_##x##_end - machdep_sys_##x;
  
  #define SYSCALL3(x)					\
! 	.globl machdep_sys_##x;		\
  									\
! machdep_sys_##x##:;				\
  									\
  	push %ebx;						\
***************
*** 72,81 ****
  	int $0x80;						\
  	pop %ebx;						\
! 	ret;
  
  #define SYSCALL4(x)					\
! 	.globl _machdep_sys_##x;		\
  									\
! _machdep_sys_##x##:;				\
  									\
  	push %ebx;						\
--- 99,111 ----
  	int $0x80;						\
  	pop %ebx;						\
! 	ret; \
! 	.type machdep_sys_##x, @function; \
! .L_machdep_sys_##x##_end:; \
! 	.size machdep_sys_##x,.L_machdep_sys_##x##_end - machdep_sys_##x;
  
  #define SYSCALL4(x)					\
! 	.globl machdep_sys_##x;		\
  									\
! machdep_sys_##x##:;				\
  									\
  	push %ebx;						\
***************
*** 89,98 ****
  	pop %esi;						\
  	pop %ebx;						\
! 	ret;
  
  #define SYSCALL5(x)					\
! 	.globl _machdep_sys_##x;		\
  									\
! _machdep_sys_##x##:;				\
  									\
  	push %ebx;						\
--- 119,131 ----
  	pop %esi;						\
  	pop %ebx;						\
! 	ret; \
! 	.type machdep_sys_##x, @function; \
! .L_machdep_sys_##x##_end:; \
! 	.size machdep_sys_##x,.L_machdep_sys_##x##_end - machdep_sys_##x;
  
  #define SYSCALL5(x)					\
! 	.globl machdep_sys_##x;		\
  									\
! machdep_sys_##x##:;				\
  									\
  	push %ebx;						\
***************
*** 109,113 ****
  	pop %esi;						\
  	pop %ebx;						\
! 	ret;
  
  /* =========================================================================
--- 142,149 ----
  	pop %esi;						\
  	pop %ebx;						\
! 	ret; \
! 	.type machdep_sys_##x, @function; \
! .L_machdep_sys_##x##_end:; \
! 	.size machdep_sys_##x,.L_machdep_sys_##x##_end - machdep_sys_##x;
  
  /* =========================================================================
***************
*** 252,261 ****
   * machdep_sys_stat()
   */
! SYSCALL2(stat)
  
  /* ==========================================================================
   * machdep_sys_fstat()
   */
! SYSCALL2(fstat)
  
  /* ==========================================================================
--- 288,297 ----
   * machdep_sys_stat()
   */
! STATCALL2(stat)
  
  /* ==========================================================================
   * machdep_sys_fstat()
   */
! STATCALL2(fstat)
  
  /* ==========================================================================
***************
*** 270,276 ****
   * machdep_sys_select()
   */
! 	.globl _machdep_sys_select;		\
  									\
! _machdep_sys_select:;				\
  									\
  	push %ebx;						\
--- 306,312 ----
   * machdep_sys_select()
   */
! 	.globl machdep_sys_select;		\
  									\
! machdep_sys_select:;				\
  									\
  	push %ebx;						\
***************
*** 279,283 ****
  	int $0x80;						\
  	pop %ebx;						\
! 	ret;
  
  /* ==========================================================================
--- 315,322 ----
  	int $0x80;						\
  	pop %ebx;						\
! 	ret; \
! 	.type machdep_sys_select, @function; \
! .L_machdep_sys_select_end:; \
! 	.size machdep_sys_select,.L_machdep_sys_select_end - machdep_sys_select;
  
  /* ==========================================================================
***************
*** 303,309 ****
   * machdep_sys_sigsuspend()
   */
! 	.globl _machdep_sys_sigsuspend;		
  
! _machdep_sys_sigsuspend:;				
  
      push %ebp;
--- 342,348 ----
   * machdep_sys_sigsuspend()
   */
! 	.globl machdep_sys_sigsuspend;		
  
! machdep_sys_sigsuspend:;				
  
      push %ebp;
***************
*** 322,324 ****
--- 361,367 ----
      pop %ebp;
  	ret;
+ 	.type machdep_sys_sigsuspend, @function;
+ .L_machdep_sys_sigsuspend_end:;
+ 	.size machdep_sys_sigsuspend,.L_machdep_sys_sigsuspend_end - machdep_sys_sigsuspend;
+ 
  
diff -r -C 2 pthreads-1_60_beta2/pthreads/fd.c pthreads/pthreads/fd.c
*** pthreads-1_60_beta2/pthreads/fd.c	Sun Mar 26 02:45:10 1995
--- pthreads/pthreads/fd.c	Wed Apr 26 00:00:18 1995
***************
*** 792,796 ****
--- 792,800 ----
   * Might want to indirect this.
   */
+ #ifdef __linux__
+ int _fxstat(int dummy, int fd, struct stat *buf)
+ #else
  int fstat(int fd, struct stat *buf)
+ #endif
  {
  	int ret;
diff -r -C 2 pthreads-1_60_beta2/pthreads/wrapper.c pthreads/pthreads/wrapper.c
*** pthreads-1_60_beta2/pthreads/wrapper.c	Sat Feb 11 23:54:14 1995
--- pthreads/pthreads/wrapper.c	Wed Apr 26 00:04:20 1995
***************
*** 119,123 ****
--- 119,127 ----
   * stat()
   */
+ #ifdef __linux__
+ int _xstat(int dummy, const char *path, struct stat *buf)
+ #else
  int stat(const char * path, struct stat * buf)
+ #endif
  {
  	int ret;
diff -r -C 2 pthreads-1_60_beta2/stdio/GNUmakefile.inc pthreads/stdio/GNUmakefile.inc
*** pthreads-1_60_beta2/stdio/GNUmakefile.inc	Sat Feb 11 23:55:56 1995
--- pthreads/stdio/GNUmakefile.inc	Thu Apr 27 13:35:17 1995
***************
*** 7,11 ****
  
  SRCS:=	clrerr.c fclose.c fdopen.c feof.c ferror.c fflush.c fgetc.c \
! 	fgetline.c fgetpos.c fgets.c fileno.c findfp.c flags.c fopen.c \
  	fprintf.c fpurge.c fputc.c fputs.c fread.c freopen.c fscanf.c \
  	fseek.c fsetpos.c ftell.c funopen.c fvwrite.c fwalk.c fwrite.c \
--- 7,11 ----
  
  SRCS:=	clrerr.c fclose.c fdopen.c feof.c ferror.c fflush.c fgetc.c \
! 	fgetline.c fgets.c fileno.c findfp.c flags.c fopen.c \
  	fprintf.c fpurge.c fputc.c fputs.c fread.c freopen.c fscanf.c \
  	fseek.c fsetpos.c ftell.c funopen.c fvwrite.c fwalk.c fwrite.c \
***************
*** 16,20 ****
  	vfscanf.c vprintf.c vscanf.c vsnprintf.c vsprintf.c vsscanf.c \
  	wsetup.c putc_unlocked.c putchar_unlocked.c getc_unlocked.c \
! 	getchar_unlocked.c strerror.c wbuf.c $(SRCS)
  
  # tempnam.c tmpnam.c tmpfile.c
--- 16,20 ----
  	vfscanf.c vprintf.c vscanf.c vsnprintf.c vsprintf.c vsscanf.c \
  	wsetup.c putc_unlocked.c putchar_unlocked.c getc_unlocked.c \
! 	getchar_unlocked.c strerror.c wbuf.c $(SRCS) #fgetpos.c
  
  # tempnam.c tmpnam.c tmpfile.c
diff -r -C 2 pthreads-1_60_beta2/stdlib/GNUmakefile.inc pthreads/stdlib/GNUmakefile.inc
*** pthreads-1_60_beta2/stdlib/GNUmakefile.inc	Fri Mar 24 00:45:38 1995
--- pthreads/stdlib/GNUmakefile.inc	Wed Apr 26 01:28:47 1995
***************
*** 4,7 ****
  VPATH:= ${VPATH}:${srcdir}/stdlib
  
! SRCS:= abort.c exit.c strtod.c getopt.c rand.c random.c strtol.c strtoul.c \
         system.c $(SRCS)
--- 4,8 ----
  VPATH:= ${VPATH}:${srcdir}/stdlib
  
! SRCS:= abort.c exit.c strtod.c getopt.c rand.c random.c strtoul.c \
         system.c $(SRCS)
+ #strtol.c taken out
\ No newline at end of file
diff -r -C 2 pthreads-1_60_beta2/tests/test_preemption_float.c pthreads/tests/test_preemption_float.c
*** pthreads-1_60_beta2/tests/test_preemption_float.c	Fri Mar 24 00:45:58 1995
--- pthreads/tests/test_preemption_float.c	Tue May 23 17:24:53 1995
***************
*** 13,17 ****
  void *log_loop (void *x) {
    int i;
!   double d, d1, d2;
    /* sleep (1); */
    for (i = 0; i < limit; i++) {
--- 13,17 ----
  void *log_loop (void *x) {
    int i;
!   volatile double d, d1, d2;
    /* sleep (1); */
    for (i = 0; i < limit; i++) {
***************
*** 32,36 ****
  void *trig_loop (void *x) {
    int i;
!   double d, d1, d2;
    /* sleep (1);  */
    for (i = 0; i < limit; i++) {
--- 32,36 ----
  void *trig_loop (void *x) {
    int i;
!   volatile double d, d1, d2;
    /* sleep (1);  */
    for (i = 0; i < limit; i++) {
