diff -c -r skill-4.1.2/Config skill-4.1.4/Config
*** skill-4.1.2/Config	2005-04-06 19:45:04.000000000 -0400
--- skill-4.1.4/Config	2006-10-08 22:02:27.000000000 -0400
***************
*** 1,6 ****
  #!/bin/sh
  #
! #	$Id: Config,v 1.24 2005/04/06 23:44:58 forys Exp $
  #
  #	Config - edit skill Makefile filling in OSTYPE, COPTS, LIBS, and
  #		possibly BINGRP and BINMOD.
--- 1,6 ----
  #!/bin/sh
  #
! #	$Id: Config,v 1.25 2006/10/09 02:02:21 forys Exp $
  #
  #	Config - edit skill Makefile filling in OSTYPE, COPTS, LIBS, and
  #		possibly BINGRP and BINMOD.
***************
*** 40,46 ****
  if [ -n "${UNAME_OS}" -a -n "${UNAME_REV}" ]; then
  	case "${UNAME_OS}" in
  	    AIX)
! 		OS=aix3
  		;;
  	    CYGWIN*)
  		OS=cygwin1
--- 40,50 ----
  if [ -n "${UNAME_OS}" -a -n "${UNAME_REV}" ]; then
  	case "${UNAME_OS}" in
  	    AIX)
! 		if [ "`exec 2>/dev/null; uname -v`" -ge 5 ]; then
! 			OS=aix5
! 		else
! 			OS=aix3
! 		fi
  		;;
  	    CYGWIN*)
  		OS=cygwin1
***************
*** 141,153 ****
  fi
  
  if [ -z "${OS}" ]; then
! 	case "`exec 2>/dev/null; head -2 /etc/motd`" in
! 	    *"IBM AIX Version 3"*)
  		OS=aix3
  		;;
! 	    *"IBM AIX Version 4"*)
  		OS=aix3
  		;;
  	    *"DYNIX(R) V3."*)
  		OS=dynix3
  		;;
--- 145,160 ----
  fi
  
  if [ -z "${OS}" ]; then
! 	case "`exec 2>/dev/null; head -5 /etc/motd`" in
! 	    *"AIX Version 3"*)
  		OS=aix3
  		;;
! 	    *"AIX Version 4"*)
  		OS=aix3
  		;;
+ 	    *"AIX Version 5"*)
+ 		OS=aix5
+ 		;;
  	    *"DYNIX(R) V3."*)
  		OS=dynix3
  		;;
***************
*** 368,373 ****
--- 375,384 ----
  	;;
  
      aix3)
+ 	OSTYPE=aix-3 COPTS=-DSKILL_AIX34
+ 	;;
+ 
+     aix5)
  	OSTYPE=aix-3
  	;;
  
diff -c -r skill-4.1.2/Makefile skill-4.1.4/Makefile
*** skill-4.1.2/Makefile	2005-04-06 19:45:54.000000000 -0400
--- skill-4.1.4/Makefile	2007-05-04 16:57:23.000000000 -0400
***************
*** 1,5 ****
  #
! # $Id: Makefile,v 1.41 2005/04/06 23:45:35 forys Exp $
  #
  # First, find the CONFIGURE comments and set up the "BIN*" and "MAN*"
  # defines according to local customs.  Next, if your operating system
--- 1,5 ----
  #
! # $Id: Makefile,v 1.43 2007/05/04 20:56:28 forys Exp $
  #
  # First, find the CONFIGURE comments and set up the "BIN*" and "MAN*"
  # defines according to local customs.  Next, if your operating system
***************
*** 28,40 ****
  # DEC		Ultrix 4.2	ultrix-4
  # Encore	UMAX 4.2	umax-42		COPTS=-DNO_UID_T
  # FreeBSD	2.0-2		bsd-44		LIBS=-lkvm (kmem/2755)
! # FreeBSD	2.2.8-5.0	nbsd-44
  # HP		HP-UX 6.5	hpux-70		COPTS=-DNO_UID_T
  # HP		HP-UX 7.0	hpux-70
  # HP		HP-UX 8.0-9.1	hpux-90
  # HP		HP-UX 10.1-20	hpux-10
! # HP		HP-UX 11.0-11	hpux-10
! # IBM		AIX 3.2-4.1	aix-3
  # IBM		AOS 4.3		aos-43
  # Linux		Linux 1.0-2.2	linux-1		COPTS=-O3 LIBS="-s -N"
  # MIPS		UMIPS 2.1	umips-21	LIBS=-lmld
--- 28,41 ----
  # DEC		Ultrix 4.2	ultrix-4
  # Encore	UMAX 4.2	umax-42		COPTS=-DNO_UID_T
  # FreeBSD	2.0-2		bsd-44		LIBS=-lkvm (kmem/2755)
! # FreeBSD	2.2.8-6.2	nbsd-44
  # HP		HP-UX 6.5	hpux-70		COPTS=-DNO_UID_T
  # HP		HP-UX 7.0	hpux-70
  # HP		HP-UX 8.0-9.1	hpux-90
  # HP		HP-UX 10.1-20	hpux-10
! # HP		HP-UX 11.0-31	hpux-10
! # IBM		AIX 5.2		aix-3
! # IBM		AIX 3.2-4.1	aix-3		COPTS=-DSKILL_AIX43
  # IBM		AOS 4.3		aos-43
  # Linux		Linux 1.0-2.2	linux-1		COPTS=-O3 LIBS="-s -N"
  # MIPS		UMIPS 2.1	umips-21	LIBS=-lmld
***************
*** 95,100 ****
--- 96,103 ----
  ${OBJS}: ${HDRS}
  
  install: skill
+ 	-test -d ${DESTDIR}/${BINDIR} || mkdir -p -m 755 ${DESTDIR}/${BINDIR}
+ 	-test -d ${DESTDIR}/${MANDIR} || mkdir -p -m 755 ${DESTDIR}/${MANDIR}
  #(SysV)	filepriv -d ${DESTDIR}/${BINDIR}/skill
  	rm -f ${DESTDIR}/${BINDIR}/skill ${DESTDIR}/${MANDIR}/skill.${MANSFX}
  	rm -f ${DESTDIR}/${BINDIR}/snice ${DESTDIR}/${MANDIR}/snice.${MANSFX}
***************
*** 115,121 ****
  	./Config
  
  clean:
! 	rm -f skill snice skill.exe snice.exe *.o getproc.c
  
  lint:	getproc.c
  	lint ${COPTS} ${SRCS} ${LIBS}
--- 118,127 ----
  	./Config
  
  clean:
! 	rm -f skill snice skill.exe snice.exe *.o
! 
! distclean: clean
! 	rm -f getproc.c
  
  lint:	getproc.c
  	lint ${COPTS} ${SRCS} ${LIBS}
diff -c -r skill-4.1.2/README skill-4.1.4/README
*** skill-4.1.2/README	2005-04-06 23:09:36.000000000 -0400
--- skill-4.1.4/README	2007-05-04 16:57:38.000000000 -0400
***************
*** 20,26 ****
  ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
  
! $Id: README,v 1.56 2005/04/07 03:09:32 forys Exp $
  
  	`skill' is a program which sends signals to processes given
  any combination of user names, ttys, commands, and pids.  `snice' is
--- 20,26 ----
  ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
  
! $Id: README,v 1.58 2007/05/04 20:57:31 forys Exp $
  
  	`skill' is a program which sends signals to processes given
  any combination of user names, ttys, commands, and pids.  `snice' is
***************
*** 44,52 ****
  	DEC AXP OSF/1
  	DEC/Compaq Tru64 Unix V3.2D-2, T3.2F-1, V4.0, V5.0-1B
  	Encore UMAX 4.2
! 	FreeBSD 2.0-2, 3.1, 4.4-11, 5.0-3
! 	HP-UX 6.5, 7.0, 8.0, 9.0-5, 10.1-20, 11.0-23
! 	IBM AIX 3.1-2, 4.1
  	IBM AOS 4.3
  	Linux 1.0-2, 2.1, 2.2, 2.4
  	MIPS UMIPS 2.1
--- 44,52 ----
  	DEC AXP OSF/1
  	DEC/Compaq Tru64 Unix V3.2D-2, T3.2F-1, V4.0, V5.0-1B
  	Encore UMAX 4.2
! 	FreeBSD 2.0-2, 3.1, 4.4-11, 5.0-3, 6.0-2
! 	HP-UX 6.5, 7.0, 8.0, 9.0-5, 10.1-20, 11.0-31
! 	IBM AIX 3.1-2, 4.1, 5.2
  	IBM AOS 4.3
  	Linux 1.0-2, 2.1, 2.2, 2.4
  	MIPS UMIPS 2.1
diff -c -r skill-4.1.2/argparse.c skill-4.1.4/argparse.c
*** skill-4.1.2/argparse.c	2005-04-06 19:43:29.000000000 -0400
--- skill-4.1.4/argparse.c	2016-02-02 15:46:45.000000000 -0500
***************
*** 21,27 ****
  */
  
  #ifndef lint
! static char rcsid[] = "$Id: argparse.c,v 1.17 2005/04/06 23:43:25 forys Exp $";
  #endif
  
  #define	NO_AEXTERN
--- 21,27 ----
  */
  
  #ifndef lint
! static char rcsid[] = "$Id: argparse.c,v 1.18 2016/02/02 20:46:39 forys Exp $";
  #endif
  
  #define	NO_AEXTERN
***************
*** 29,34 ****
--- 29,36 ----
  #undef	NO_AEXTERN
  
  #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
  #include <ctype.h>
  #include <pwd.h>
  
diff -c -r skill-4.1.2/conf.h skill-4.1.4/conf.h
*** skill-4.1.2/conf.h	2005-04-06 19:45:20.000000000 -0400
--- skill-4.1.4/conf.h	2016-02-02 15:48:05.000000000 -0500
***************
*** 20,26 ****
  ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
  
! /* $Id: conf.h,v 1.20 2005/04/06 23:45:10 forys Exp $ */
  
  #include <sys/param.h>
  #ifdef	NO_TYPES_INC		/* normally, <sys/param.h> includes this */
--- 20,26 ----
  ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
  
! /* $Id: conf.h,v 1.21 2016/02/02 20:47:26 forys Exp $ */
  
  #include <sys/param.h>
  #ifdef	NO_TYPES_INC		/* normally, <sys/param.h> includes this */
***************
*** 145,151 ****
  	regex_t *_r;						\
  	if ((_r = (regex_t *)malloc(sizeof *_r)) == NULL) {	\
  		fprintf(stderr,					\
! 			"%s: RegexComp: out of memory (wanted %u bytes)\n", \
  			ProgName, sizeof *_r);			\
  		exit(EX_SERR);					\
  	}							\
--- 145,151 ----
  	regex_t *_r;						\
  	if ((_r = (regex_t *)malloc(sizeof *_r)) == NULL) {	\
  		fprintf(stderr,					\
! 			"%s: RegexComp: out of memory (wanted %lu bytes)\n", \
  			ProgName, sizeof *_r);			\
  		exit(EX_SERR);					\
  	}							\
diff -c -r skill-4.1.2/machdep/aix-3.c skill-4.1.4/machdep/aix-3.c
*** skill-4.1.2/machdep/aix-3.c	2005-04-06 19:49:34.000000000 -0400
--- skill-4.1.4/machdep/aix-3.c	2006-10-08 21:59:25.000000000 -0400
***************
*** 1,5 ****
  /*
! ** Copyright (c) 1986, 1994, 1996, 2000, 2002
  **	Jeff Forys (jeffware@marjum.com).  All rights reserved.
  **
  ** Redistribution and use in source and binary forms, with or without
--- 1,5 ----
  /*
! ** Copyright (c) 1986, 1994, 1996, 2000, 2002, 2006
  **	Jeff Forys (jeffware@marjum.com).  All rights reserved.
  **
  ** Redistribution and use in source and binary forms, with or without
***************
*** 21,27 ****
  */
  
  #ifndef lint
! static char rcsid[] = "$Id: aix-3.c,v 1.9 2005/04/06 23:49:34 forys Exp $";
  #endif
  
  #define	NO_MEXTERN
--- 21,27 ----
  */
  
  #ifndef lint
! static char rcsid[] = "$Id: aix-3.c,v 1.10 2006/10/09 01:58:11 forys Exp $";
  #endif
  
  #define	NO_MEXTERN
***************
*** 34,39 ****
--- 34,62 ----
  #include <stdio.h>
  
  /*
+  * For AIX 3 and AIX 4, #define the SKILL_AIX34 macro.
+  * For AIX 5 (and beyond), this file should compile correctly.
+  */
+ #ifdef SKILL_AIX34
+ #define	SKILL_P_STRUCT		struct procinfo
+ #define	SKILL_P_STATE(p)	(p)->pi_stat
+ #define	SKILL_P_FLAGS(p)	(p)->pi_flag
+ #define	SKILL_PU_TTYP(p,u)	(u)->ui_ttyp
+ #define	SKILL_PU_TTYD(p,u)	(u)->ui_ttyd
+ #define	SKILL_PU_COMM(p,u)	(u)->ui_comm
+ #define	SKILL_NOTTY		(-1)
+ #else
+ #define	SKILL_P_STRUCT		struct procentry64
+ #define	SKILL_P_STATE(p)	(p)->pi_state
+ #define	SKILL_P_FLAGS(p)	(p)->pi_flags
+ #define	SKILL_PU_TTYP(p,u)	(p)->pi_ttyp
+ #define	SKILL_PU_TTYD(p,u)	(p)->pi_ttyd
+ #define	SKILL_PU_COMM(p,u)	(p)->pi_comm
+ #define	SKILL_NOTTY		(0)
+ #include <stdlib.h>
+ #endif
+ 
+ /*
   * Define SigNames, NSig, and TtyDevDir here; they are used by other
   * routines and must be global.  Everyone seems to have their own
   * idea as to what NSIG should be.  Here, `NSig' is the number of
***************
*** 49,55 ****
--- 72,82 ----
  	"37", "38", "39", "40", "41", "42",			/* 37 - 42 */
  	"43", "44", "45", "46", "47", "48",			/* 43 - 48 */
  	"49", "50", "51", "52", "53", "54",			/* 49 - 54 */
+ #ifdef	SKILL_AIX34
  	"55", "56", "57", "58", "59", "GRANT",			/* 55 - 60 */
+ #else
+ 	"55", "56", "57", "58", "CPUFAIL", "GRANT",		/* 55 - 60 */
+ #endif
  	"RETRACT", "SOUND", "SAK", "64",			/* 61 - 64 */
  };
  int NSig = NSIG;
***************
*** 138,145 ****
--- 165,178 ----
  		return(setpriority(PRIO_PROCESS, (int)pid, SigPri));
  }
  
+ #ifdef SKILL_AIX34
  /* disable regular expresions: regex(3) availability unknown */
  NULL_REGEX_FUNCS
+ #else
+ /* OS supports POSIX-style regular expressions */
+ #include <regex.h>
+ REAL_REGEX_FUNCS
+ #endif
  
  /*
   * Now, set up everything we need to write a GetProc() routine.
***************
*** 174,180 ****
  
  extern	off_t lseek();
  
! #define	NPROCS	256	/* size of `procs' struct (if too small, use calloc) */
  
  /*
   * GetProc()
--- 207,213 ----
  
  extern	off_t lseek();
  
! #define	NPROCS	1024	/* size of `procs' struct (if too small, use calloc) */
  
  /*
   * GetProc()
***************
*** 191,203 ****
  {
  	extern int errno;
  	extern char *SysErr();
! 	static struct procinfo pinfo[NPROCS], *procsp;
  	static struct ProcInfo procinfo;
- 	register struct procinfo *aproc;
- 	register struct userinfo *auser;
  	static int thisproc = 0;
  	static int initialized = 0;
  	static int needuser = 1;		/* Fflag support */
  
  	/*
  	 * Read in all the processes at once, into a large block of memory;
--- 224,240 ----
  {
  	extern int errno;
  	extern char *SysErr();
! 	static SKILL_P_STRUCT pinfo[NPROCS], *procsp;
! 	register SKILL_P_STRUCT *aproc;
  	static struct ProcInfo procinfo;
  	static int thisproc = 0;
  	static int initialized = 0;
  	static int needuser = 1;		/* Fflag support */
+ #ifdef SKILL_AIX34
+ 	register struct userinfo *auser;
+ #else
+ 	pid_t procsidx;
+ #endif
  
  	/*
  	 * Read in all the processes at once, into a large block of memory;
***************
*** 215,222 ****
  		if (initialized)
  			return((struct ProcInfo *)NULL);
  
! 		pisize = sizeof(struct procinfo);
! 		if ((thisproc = getproc(pinfo, (u_int)NPROCS, pisize)) < 0) {
  			/*
  			 * We apparently have more then NPROCS processes
  			 * running on this machine.  Ideally, one should
--- 252,267 ----
  		if (initialized)
  			return((struct ProcInfo *)NULL);
  
! 		pisize = sizeof(SKILL_P_STRUCT);
! #ifdef SKILL_AIX34
! 		if ((thisproc = getproc(pinfo, (u_int)NPROCS, pisize)) < 0)
! #else
! 		procsidx = 0;
! 		if (((thisproc = getprocs64(pinfo, pisize, NULL, 0,
! 				&procsidx, (u_int)NPROCS)) < 0) ||
! 		    thisproc == NPROCS)
! #endif
! 		{
  			/*
  			 * We apparently have more then NPROCS processes
  			 * running on this machine.  Ideally, one should
***************
*** 238,258 ****
  			errno = nprocs;
  
  			nprocs = NPROCS;
! 			while (errno == ENOSPC && nprocs <= maxnprocs) {
  				nprocs <<= 1;
! 				if ((procsp = (struct procinfo *)
  				     calloc(nprocs, pisize)) == NULL) {
  					fprintf(stderr, errstr, ProgName,
  					        "getproc", "out of memory");
  					exit(EX_SERR);
  				}
  				errno = 0;
  				thisproc = getproc(procsp, nprocs, pisize);
  				if (thisproc < 0 && errno != ENOSPC) {
  					fprintf(stderr, errstr, ProgName,
  						"getproc", SysErr());
  					exit(EX_SERR);
! 				} else if (thisproc == nprocs)
  					break;
  				free((void *)procsp);
  			}
--- 283,309 ----
  			errno = nprocs;
  
  			nprocs = NPROCS;
! 			while (nprocs <= maxnprocs) {
  				nprocs <<= 1;
! 				if ((procsp = (SKILL_P_STRUCT *)
  				     calloc(nprocs, pisize)) == NULL) {
  					fprintf(stderr, errstr, ProgName,
  					        "getproc", "out of memory");
  					exit(EX_SERR);
  				}
  				errno = 0;
+ #ifdef SKILL_AIX34
  				thisproc = getproc(procsp, nprocs, pisize);
+ #else
+ 				procsidx = 0;
+ 				thisproc = getprocs64(procsp, pisize, NULL, 0,
+ 					&procsidx, nprocs);
+ #endif
  				if (thisproc < 0 && errno != ENOSPC) {
  					fprintf(stderr, errstr, ProgName,
  						"getproc", SysErr());
  					exit(EX_SERR);
! 				} else if (thisproc < nprocs)
  					break;
  				free((void *)procsp);
  			}
***************
*** 281,287 ****
  		aproc = procsp++;
  		thisproc--;
  
! 		if (aproc->pi_stat != SNONE) {
  			/*
  			 * Make sure this isn't a "zombie" or "exiting"
  			 * process.  If it is, we have all the information
--- 332,338 ----
  		aproc = procsp++;
  		thisproc--;
  
! 		if (SKILL_P_STATE(aproc) != SNONE) {
  			/*
  			 * Make sure this isn't a "zombie" or "exiting"
  			 * process.  If it is, we have all the information
***************
*** 291,301 ****
  			procinfo.pi_pid = (pid_T) aproc->pi_pid;
  			procinfo.pi_uid = (uid_T) aproc->pi_uid;
  
! 			if (aproc->pi_stat == SZOMB) {	/* zombie */
  				static char *zombie = "<defunct>";
  				procinfo.pi_flags |= PI_ZOMBIE;
  				procinfo.pi_cmd = zombie;
! 			} else if (aproc->pi_flag & SEXIT) {
  				static char *exiting = "<exiting>";
  				procinfo.pi_flags |= PI_SWEXIT;
  				procinfo.pi_cmd = exiting;
--- 342,352 ----
  			procinfo.pi_pid = (pid_T) aproc->pi_pid;
  			procinfo.pi_uid = (uid_T) aproc->pi_uid;
  
! 			if (SKILL_P_STATE(aproc) == SZOMB) { /* zombie */
  				static char *zombie = "<defunct>";
  				procinfo.pi_flags |= PI_ZOMBIE;
  				procinfo.pi_cmd = zombie;
! 			} else if (SKILL_P_FLAGS(aproc) & SEXIT) {
  				static char *exiting = "<exiting>";
  				procinfo.pi_flags |= PI_SWEXIT;
  				procinfo.pi_cmd = exiting;
***************
*** 306,336 ****
  
  			if (procinfo.pi_flags || !needuser)
  				return(&procinfo);
  			else {
  				static struct userinfo uinfo;
! 				if (getuser(aproc, sizeof(struct procinfo),
  				            &uinfo,sizeof(struct userinfo)) < 0)
  					auser = NULL;
  				else
  					auser = &uinfo;
  			}
  		}
  
! 	} while (aproc->pi_stat == SNONE || auser == NULL);
  
  	/*
  	 * We now have a process (`aproc').
  	 * Fill in the rest of `procinfo'.
  	 */
! 	if (auser->ui_ttyp != -1) {	/* has a controlling tty */
  		procinfo.pi_flags |= PI_CTLTTY;
! 		procinfo.pi_tty = (tty_T) auser->ui_ttyd;
  	} else {
  		procinfo.pi_tty = (tty_T)-2;
  	}
  
  	/* set path-stripped command name */
! 	SETCMD(procinfo.pi_cmd, auser->ui_comm, MAXCOMLEN)
  
  	return(&procinfo);
  }
--- 357,394 ----
  
  			if (procinfo.pi_flags || !needuser)
  				return(&procinfo);
+ #ifdef SKILL_AIX34
  			else {
  				static struct userinfo uinfo;
! 				if (getuser(aproc, sizeof(SKILL_P_STRUCT),
  				            &uinfo,sizeof(struct userinfo)) < 0)
  					auser = NULL;
  				else
  					auser = &uinfo;
  			}
+ #endif
  		}
  
! 	}
! #ifdef SKILL_AIX34
!  	while (SKILL_P_STATE(aproc) == SNONE || auser == NULL);
! #else
!  	while (SKILL_P_STATE(aproc) == SNONE);
! #endif
  
  	/*
  	 * We now have a process (`aproc').
  	 * Fill in the rest of `procinfo'.
  	 */
! 	if (SKILL_PU_TTYP(aproc,auser) != SKILL_NOTTY) { /* controlling tty */
  		procinfo.pi_flags |= PI_CTLTTY;
! 		procinfo.pi_tty = (tty_T) SKILL_PU_TTYD(aproc,auser);
  	} else {
  		procinfo.pi_tty = (tty_T)-2;
  	}
  
  	/* set path-stripped command name */
! 	SETCMD(procinfo.pi_cmd, SKILL_PU_COMM(aproc,auser), MAXCOMLEN)
  
  	return(&procinfo);
  }
diff -c -r skill-4.1.2/machdep/sys-5r4.c skill-4.1.4/machdep/sys-5r4.c
*** skill-4.1.2/machdep/sys-5r4.c	2005-04-06 19:49:35.000000000 -0400
--- skill-4.1.4/machdep/sys-5r4.c	2006-10-08 22:00:03.000000000 -0400
***************
*** 1,5 ****
  /*
! ** Copyright (c) 1986, 1994, 1996, 2000, 2002
  **	Jeff Forys (jeffware@marjum.com).  All rights reserved.
  **
  ** Redistribution and use in source and binary forms, with or without
--- 1,5 ----
  /*
! ** Copyright (c) 1986, 1994, 1996, 2000, 2002, 2006
  **	Jeff Forys (jeffware@marjum.com).  All rights reserved.
  **
  ** Redistribution and use in source and binary forms, with or without
***************
*** 23,29 ****
  */
  
  #ifndef lint
! static char rcsid[] = "$Id: sys-5r4.c,v 1.21 2005/04/06 23:49:35 forys Exp $";
  #endif
  
  #define	NO_MEXTERN
--- 23,29 ----
  */
  
  #ifndef lint
! static char rcsid[] = "$Id: sys-5r4.c,v 1.23 2006/10/09 01:59:56 forys Exp $";
  #endif
  
  #define	NO_MEXTERN
***************
*** 99,104 ****
--- 99,113 ----
  uid_T	MyUid;			/* uid of this process */
  char	*ProgName;		/* program name */
  
+ #ifdef sun
+ int timeout;
+ void
+ alarmhdlr()
+ {
+ 	timeout = 1;
+ }
+ #endif
+ 
  /*
   * This is the machine-dependent initialization routine.
   *
***************
*** 120,125 ****
--- 129,135 ----
  
  #ifdef sun
  	{
+ 		struct sigaction avec;
  		extern int SigsPerLine;
  		int sig;
  
***************
*** 145,150 ****
--- 155,165 ----
  				sprintf(SigMap[sig], "%d", sig);
  		}
  # endif
+ 		sigemptyset (&avec.sa_mask);
+ 		sigaddset (&avec.sa_mask, SIGALRM);
+ 		avec.sa_flags = 0;			/* no restart */
+ 		avec.sa_handler = alarmhdlr;
+ 		(void) sigaction(SIGALRM, &avec, NULL);
  	}
  #endif
  
***************
*** 239,245 ****
  	int fd;
  
  	/*
! 	 * If this is our first time here, open the proc directory,...
  	 */
  	if (dirfp == NULL && (dirfp=opendir(ProcDir)) == NULL) {
  		fprintf(stderr, "%s: %s: %s\n", ProgName, ProcDir, SysErr());
--- 254,260 ----
  	int fd;
  
  	/*
! 	 * If this is our first time here, open the proc directory...
  	 */
  	if (dirfp == NULL && (dirfp=opendir(ProcDir)) == NULL) {
  		fprintf(stderr, "%s: %s: %s\n", ProgName, ProcDir, SysErr());
***************
*** 250,257 ****
  		if (strcmp(dp->d_name,".") == 0 || strcmp(dp->d_name,"..") == 0)
  			continue;
  		(void) sprintf(flnm, ProcFil, dp->d_name);
! 		if ((fd = open(flnm, O_RDONLY)) < 0) {
  			MissedProcCnt++;
  			continue;	/* ignore procs we don't own */
  		}
  
--- 265,284 ----
  		if (strcmp(dp->d_name,".") == 0 || strcmp(dp->d_name,"..") == 0)
  			continue;
  		(void) sprintf(flnm, ProcFil, dp->d_name);
! #ifdef sun
! 		timeout = 0;
! 		alarm(2);
! #endif
! 		fd = open(flnm, O_RDONLY);
! #ifdef sun
! 		alarm(0);
! #endif
! 		if (fd < 0) {
  			MissedProcCnt++;
+ #ifdef sun
+ 			if (Wflag && timeout)
+ 				printf("Warning: open(%s) blocked\n", flnm);
+ #endif
  			continue;	/* ignore procs we don't own */
  		}
  
diff -c -r skill-4.1.2/main.c skill-4.1.4/main.c
*** skill-4.1.2/main.c	2005-04-06 19:43:13.000000000 -0400
--- skill-4.1.4/main.c	2016-02-02 15:55:17.000000000 -0500
***************
*** 24,53 ****
   * skill - send signals to processes by tty, user name, command or proc id.
   * snice - reprioritize processes by tty, user name, command or proc id.
   *
!  * Version 4.1.2
   */
  
  #ifndef lint
! static char rcsid[] = "$Id: main.c,v 1.40 2005/04/06 23:42:48 forys Exp $";
  /*
   * SCCS version release number is manually updated (for what(1), etc).
!  * If you use SCCS, please use last extension for version (e.g. "4.1.2.1").
   */
  static char sccsid[] = 
! 	"@(#)skill	4.1.2.0 (jeffware@marjum.com) 04/06/05";
  #endif
  
! const char *Version = "4.1.2 20050406";
  
  const char *CopyrightVersion = "%s %s\n\nCopyright (c) 1986, 1994, 1996, 2000, 2002 Jeff Forys.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, is permitted under the terms specified in the source\ncode (and manual pages).\n";
  
  #include "conf.h"
  
  #include <stdio.h>
  #include <errno.h>
  #include <pwd.h>
  
  /*
   * Processes which could not be checked -- usually due to permission
   * problems (SunOS 4.1, SysVR4) -- are tallied in "MissedProcCnt".
   * The machine dependent code is responsible for incrementing this;
--- 24,61 ----
   * skill - send signals to processes by tty, user name, command or proc id.
   * snice - reprioritize processes by tty, user name, command or proc id.
   *
!  * Version 4.1.4
   */
  
  #ifndef lint
! static char rcsid[] = "$Id: main.c,v 1.43 2016/02/02 20:54:39 forys Exp $";
  /*
   * SCCS version release number is manually updated (for what(1), etc).
!  * If you use SCCS, please use last extension for version (e.g. "4.1.4.1").
   */
  static char sccsid[] = 
! 	"@(#)skill	4.1.4.0 (jeffware@marjum.com) 05/04/07";
  #endif
  
! const char *Version = "4.1.4 20070504";
  
  const char *CopyrightVersion = "%s %s\n\nCopyright (c) 1986, 1994, 1996, 2000, 2002 Jeff Forys.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, is permitted under the terms specified in the source\ncode (and manual pages).\n";
  
  #include "conf.h"
  
  #include <stdio.h>
+ #include <stdlib.h>
  #include <errno.h>
  #include <pwd.h>
  
  /*
+  * _LP64: 64-bit ABIs (e.g. SPARC V9) where sys_errlist[] not visible.
+  */
+ #if defined(HAS_STRERROR) || defined(_LP64)
+ #include <string.h>
+ #endif
+ 
+ /*
   * Processes which could not be checked -- usually due to permission
   * problems (SunOS 4.1, SysVR4) -- are tallied in "MissedProcCnt".
   * The machine dependent code is responsible for incrementing this;
***************
*** 62,67 ****
--- 70,76 ----
  	char *argv[];
  {
  	extern char *SysErr(), *WhoIs();
+ 	extern int Recorded();
  	register struct ProcInfo *proc;	/* process we are examining */
  	int reterr = -1;		/* -1:matchless, 0:okay, 1:error(s) */
  	register int i;
***************
*** 150,155 ****
--- 159,167 ----
  		if (PID == MyPid || PID == 0)	/* ignore self */
  			continue;
  
+ 		if (Recorded(PID))		/* record/ignore duplicates */
+ 			continue;
+ 
  		if (Iflag || (!Nflag && (FLAGS & PI_ASKUSR))) {	/* ask user */
  			static char yesno[10];
  
***************
*** 279,284 ****
--- 291,347 ----
  }
  
  /*
+  * Recorded(pid)
+  *
+  * Some OSes report the same PID multiple times, once per thread.
+  * Since there's no need to act on a process multiple times, this
+  * function is called to record that we are about to act on 'pid'.
+  *
+  * Return value: '1' if we've already acted on it, '0' if not.
+  *
+  * Note: caller ensures that we are never called with (pid == 0).
+  */
+ int
+ Recorded(pid)
+ 	pid_T pid;
+ {
+ 	static pid_T prev_pid, *pptr_cur, pids[2048];
+ 	pid_T *pptr;
+ 
+ 	/*
+ 	 * Duplicates often come one after the other, so this simple
+ 	 * cache of the previous pid obviates a search through pids[].
+ 	 *
+ 	 * On these systems, even if pids[] becomes full, we'll still
+ 	 * not see duplicate pids since the cache continues to operate.
+ 	 */
+ 	if (prev_pid == pid)
+ 		return 1;
+ 	else
+ 		prev_pid = pid;
+ 
+ 	/*
+ 	 * If this is the first time, initialize pptr_cur pointer.
+ 	 * Else, search for 'pid' and return '1' if found.
+ 	 */
+ 	if (pptr_cur == NULL)		/* first time; init and assign pid */
+ 		pptr_cur = pids;
+ 	else
+ 		for (pptr = pids; pptr < pptr_cur; pptr++)
+ 			if (*pptr == pid)
+ 				return 1;
+ 
+ 	/*
+ 	 * Either "first time" or "not found" ... either way, copy
+ 	 * this pid to the end of pids[] (provided there is room).
+ 	 */
+ 	if (pptr_cur < &pids[sizeof(pids) / sizeof(pid_T)])
+ 		*pptr_cur++ = pid;
+ 
+ 	return 0;
+ }
+ 
+ /*
   * Usage(error)
   *
   * The user typed something incorrect; explain their mistake (encoded
***************
*** 316,328 ****
  }
  
  /*
-  * _LP64: 64-bit ABIs (e.g. SPARC V9) where sys_errlist[] not visible.
-  */
- #if defined(HAS_STRERROR) || defined(_LP64)
- #include <string.h>
- #endif
- 
- /*
   * SysErr()
   *
   * Return the error message described by `errno'.
--- 379,384 ----
diff -c -r skill-4.1.2/skill.1 skill-4.1.4/skill.1
*** skill-4.1.2/skill.1	2005-04-06 19:43:51.000000000 -0400
--- skill-4.1.4/skill.1	2007-07-02 09:48:21.000000000 -0400
***************
*** 19,25 ****
  .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  .\"
! .\" $Id: skill.1,v 1.21 2005/04/06 23:43:34 forys Exp $
  .\"
  .\" skill - send signals to processes by tty, user name, command or proc id.
  .\" skill - reprioritize processes by tty, user name, command or proc id.
--- 19,25 ----
  .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  .\"
! .\" $Id: skill.1,v 1.22 2007/07/02 13:47:58 forys Exp $
  .\"
  .\" skill - send signals to processes by tty, user name, command or proc id.
  .\" skill - reprioritize processes by tty, user name, command or proc id.
***************
*** 66,76 ****
  .PP
  Options accepted by both commands are as follows:
  .IP \-a
! When run by an unprivileged user, processes that belong to other users
! are quietly ignored.  In all mode, this internal filter is disabled.
  It may be used in conjunction with the `-n' flag to display a set of
  processes that match a specified criteria.  This flag has no effect
! for the super-user.
  .IP \-f
  In fast mode, the machine-dependent code responsible for reading
  processes is allowed to make decisions to improve speed at the
--- 66,77 ----
  .PP
  Options accepted by both commands are as follows:
  .IP \-a
! Normally, when run by an unprivileged user, processes that belong
! to other users will not be seen.  In show-all-processes mode, this
! internal filter is disabled.
  It may be used in conjunction with the `-n' flag to display a set of
  processes that match a specified criteria.  This flag has no effect
! when run as the super-user.
  .IP \-f
  In fast mode, the machine-dependent code responsible for reading
  processes is allowed to make decisions to improve speed at the
