aboutsummaryrefslogtreecommitdiff
path: root/contrib/miscutil/misc_utils.c
blob: 75184439717c37eb42f006a62794a73b3136abee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
 * misc_utils.c --
 *
 * This file defines miscellaneous PostgreSQL utility functions.
 *
 * Copyright (c) 1998, Massimo Dal Zotto <dz@cs.unitn.it>
 *
 * This file is distributed under the GNU General Public License
 * either version 2, or (at your option) any later version.
 */

#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <errno.h>

#include "postgres.h"
#include "access/heapam.h"
#include "access/htup.h"
#include "access/relscan.h"
#include "access/skey.h"
#include "access/tupdesc.h"
#include "catalog/catname.h"
#include "catalog/pg_listener.h"
#include "storage/lmgr.h"
#include "utils/fmgr.h"
#include "utils/palloc.h"
#include "utils/rel.h"
#include "utils/tqual.h"

#include "misc_utils.h"

#define MIN(x,y)	((x)<=(y) ? (x) : (y))

extern int	ExecutorLimit(int limit);
extern void Async_Unlisten(char *relname, int pid);
extern int	assertTest(int val);

#ifdef ASSERT_CHECKING_TEST
extern int	assertEnable(int val);
#endif

int
query_limit(int limit)
{
	return ExecutorLimit(limit);
}

int
backend_pid()
{
	return getpid();
}

int
unlisten(char *relname)
{
	Async_Unlisten(relname, getpid());
	return 0;
}

int
max(int x, int y)
{
	return ((x > y) ? x : y);
}

int
min(int x, int y)
{
	return ((x < y) ? x : y);
}

/*
 * Return the number of active listeners on a relation name.
 */
int
active_listeners(text *relname)
{
	HeapTuple	lTuple;
	Relation	lRel;
	HeapScanDesc sRel;
	TupleDesc	tdesc;
	ScanKeyData key;
	Datum		d;
	bool		isnull;
	int			len, pid;
	int			count = 0;
	int			ourpid = getpid();
	char		listen_name[NAMEDATALEN];

	lRel = heap_openr(ListenerRelationName);
	tdesc = RelationGetDescr(lRel);
	LockRelation(lRel, AccessShareLock);

	if (relname && (VARSIZE(relname) > VARHDRSZ)) {
		len = MIN(VARSIZE(relname)-VARHDRSZ, NAMEDATALEN-1);
		strncpy(listen_name, VARDATA(relname), len);
		listen_name[len] = '\0';
		ScanKeyEntryInitialize(&key, 0,
							   Anum_pg_listener_relname,
							   F_NAMEEQ,
							   PointerGetDatum(listen_name));
		sRel = heap_beginscan(lRel, 0, SnapshotNow, 1, &key);
	} else {
		sRel = heap_beginscan(lRel, 0, SnapshotNow, 0, (ScanKey)NULL);
	}

	while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0)))
	{
		d = heap_getattr(lTuple, Anum_pg_listener_pid, tdesc, &isnull);
		pid = DatumGetInt32(d);
#ifdef HAVE_KILL
		if ((pid == ourpid) || (kill(pid, SIGTSTP) == 0)) {
			/* elog(NOTICE, "%d ok", pid); */
			count++;
		}
#else
		count++;
#endif
	}
	heap_endscan(sRel);

	UnlockRelation(lRel, AccessShareLock);
	heap_close(lRel);

	return count;
}

int
assert_enable(int val)
{
	return assertEnable(val);
}

#ifdef ASSERT_CHECKING_TEST
int
assert_test(int val)
{
	return assertTest(val);
}
#endif

/* end of file */

/*
 * Local Variables:
 *  tab-width: 4
 *  c-indent-level: 4
 *  c-basic-offset: 4
 * End:
 */