Index: backend/storage/ipc/sinval.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/storage/ipc/sinval.c,v
retrieving revision 1.63
diff -r1.63 sinval.c
466a467,500
>  * IsBackendPid -- is a given pid a running backend
>  */
> bool
> IsBackendPid(int pid)
> {
> 	bool		result = false;
> 	SISeg	   *segP = shmInvalBuffer;
> 	ProcState  *stateP = segP->procState;
> 	int			index;
>
> 	LWLockAcquire(SInvalLock, LW_SHARED);
>
> 	for (index = 0; index < segP->lastBackend; index++)
> 	{
> 		SHMEM_OFFSET pOffset = stateP[index].procStruct;
>
> 		if (pOffset != INVALID_OFFSET)
> 		{
> 			PGPROC	   *proc = (PGPROC *) MAKE_PTR(pOffset);
>
> 			if (proc->pid == pid)
> 			{
> 				result = true;
> 				break;
> 			}
> 		}
> 	}
>
> 	LWLockRelease(SInvalLock);
>
> 	return result;
> }
>
> /*
Index: backend/utils/adt/misc.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/utils/adt/misc.c,v
retrieving revision 1.33
diff -r1.33 misc.c
17a18
> #include <signal.h>
58a60,103
> }
>
>
> /*
>  * Functions to terminate a backend or cancel a query running on
>  * a different backend.
>  */
>
> static int pg_signal_backend(int pid, int sig)
> {
> 	if (!superuser())
> 		ereport(ERROR,
> 				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
> 				 (errmsg("only superuser can signal other backends"))));
>
> 	if (!IsBackendPid(pid))
> 	{
> 		/* This is just a warning so a loop-through-resultset will not abort
> 		 * if one backend terminated on it's own during the run */
> 		ereport(WARNING,
> 				(errmsg("pid %i is not a postgresql backend",pid)));
> 		return 0;
> 	}
>
> 	if (kill(pid, sig))
> 	{
> 		/* Again, just a warning to allow loops */
> 		ereport(WARNING,
> 				(errmsg("failed to send signal to backend %i: %m",pid)));
> 		return 0;
> 	}
> 	return 1;
> }
>
> Datum
> pg_terminate_backend(PG_FUNCTION_ARGS)
> {
> 	PG_RETURN_INT32(pg_signal_backend(PG_GETARG_INT32(0),SIGTERM));
> }
>
> Datum
> pg_cancel_backend(PG_FUNCTION_ARGS)
> {
> 	PG_RETURN_INT32(pg_signal_backend(PG_GETARG_INT32(0),SIGINT));
Index: include/catalog/pg_proc.h
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/include/catalog/pg_proc.h,v
retrieving revision 1.329
diff -r1.329 pg_proc.h
2799a2800,2804
> DATA(insert OID = 2171 ( pg_terminate_backend           PGNSP PGUID 12 f f t f s 1 23 "23" _null_ pg_terminate_backend - _null_ ));
> DESCR("Terminate a backend process");
> DATA(insert OID = 2172 ( pg_cancel_backend              PGNSP PGUID 12 f f t f s 1 23 "23" _null_ pg_cancel_backend - _null_ ));
> DESCR("Cancel running query on a backend process");
>
Index: include/storage/sinval.h
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/include/storage/sinval.h,v
retrieving revision 1.34
diff -r1.34 sinval.h
99a100
> extern bool IsBackendPid(int pid);
Index: include/utils/builtins.h
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/include/utils/builtins.h,v
retrieving revision 1.238
diff -r1.238 builtins.h
354a355,356
> extern Datum pg_terminate_backend(PG_FUNCTION_ARGS);
> extern Datum pg_cancel_backend(PG_FUNCTION_ARGS);

