1f08c3bdfSopenharmony_ci/*
2f08c3bdfSopenharmony_ci * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
3f08c3bdfSopenharmony_ci *
4f08c3bdfSopenharmony_ci * This program is free software; you can redistribute it and/or modify it
5f08c3bdfSopenharmony_ci * under the terms of version 2 of the GNU General Public License as
6f08c3bdfSopenharmony_ci * published by the Free Software Foundation.
7f08c3bdfSopenharmony_ci *
8f08c3bdfSopenharmony_ci * This program is distributed in the hope that it would be useful, but
9f08c3bdfSopenharmony_ci * WITHOUT ANY WARRANTY; without even the implied warranty of
10f08c3bdfSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11f08c3bdfSopenharmony_ci *
12f08c3bdfSopenharmony_ci * Further, this software is distributed without any warranty that it is
13f08c3bdfSopenharmony_ci * free of the rightful claim of any third person regarding infringement
14f08c3bdfSopenharmony_ci * or the like.  Any license provided herein, whether implied or
15f08c3bdfSopenharmony_ci * otherwise, applies only to this software file.  Patent licenses, if
16f08c3bdfSopenharmony_ci * any, provided herein do not apply to combinations of this program with
17f08c3bdfSopenharmony_ci * other software, or any other product whatsoever.
18f08c3bdfSopenharmony_ci *
19f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License along
20f08c3bdfSopenharmony_ci * with this program; if not, write the Free Software Foundation, Inc.,
21f08c3bdfSopenharmony_ci * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22f08c3bdfSopenharmony_ci *
23f08c3bdfSopenharmony_ci * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24f08c3bdfSopenharmony_ci * Mountain View, CA  94043, or:
25f08c3bdfSopenharmony_ci *
26f08c3bdfSopenharmony_ci * http://www.sgi.com
27f08c3bdfSopenharmony_ci *
28f08c3bdfSopenharmony_ci * For further information regarding this notice, see:
29f08c3bdfSopenharmony_ci *
30f08c3bdfSopenharmony_ci * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
31f08c3bdfSopenharmony_ci *
32f08c3bdfSopenharmony_ci */
33f08c3bdfSopenharmony_ci/* $Id: zoolib.c,v 1.8 2009/06/09 17:59:46 subrata_modak Exp $ */
34f08c3bdfSopenharmony_ci/*
35f08c3bdfSopenharmony_ci * ZooLib
36f08c3bdfSopenharmony_ci *
37f08c3bdfSopenharmony_ci * A Zoo is a file used to record what test tags are running at the moment.
38f08c3bdfSopenharmony_ci * If the system crashes, we should be able to look at the zoo file to find out
39f08c3bdfSopenharmony_ci * what was currently running.  This is especially helpful when running multiple
40f08c3bdfSopenharmony_ci * tests at the same time.
41f08c3bdfSopenharmony_ci *
42f08c3bdfSopenharmony_ci * The zoo file is meant to be a text file that fits on a standard console.
43f08c3bdfSopenharmony_ci * You should be able to watch it with `cat zoofile`
44f08c3bdfSopenharmony_ci *
45f08c3bdfSopenharmony_ci * zoo file format:
46f08c3bdfSopenharmony_ci * 	80 characters per line, ending with a \n
47f08c3bdfSopenharmony_ci * 	available lines start with '#'
48f08c3bdfSopenharmony_ci * 	expected line fromat: pid_t,tag,cmdline
49f08c3bdfSopenharmony_ci *
50f08c3bdfSopenharmony_ci */
51f08c3bdfSopenharmony_ci
52f08c3bdfSopenharmony_ci#include <signal.h>
53f08c3bdfSopenharmony_ci#include <stdlib.h>		/* for getenv */
54f08c3bdfSopenharmony_ci#include <string.h>
55f08c3bdfSopenharmony_ci#include "zoolib.h"
56f08c3bdfSopenharmony_ci
57f08c3bdfSopenharmony_cichar zoo_error[ZELEN];
58f08c3bdfSopenharmony_ci
59f08c3bdfSopenharmony_ci#ifdef __linux__
60f08c3bdfSopenharmony_ci/* glibc2.2 definition needs -D_XOPEN_SOURCE, which breaks other things. */
61f08c3bdfSopenharmony_ciextern int sighold(int __sig);
62f08c3bdfSopenharmony_ciextern int sigrelse(int __sig);
63f08c3bdfSopenharmony_ci#endif
64f08c3bdfSopenharmony_ci
65f08c3bdfSopenharmony_ci/* zoo_mark(): private function to make an entry to the zoo
66f08c3bdfSopenharmony_ci * 	returns 0 on success, -1 on error */
67f08c3bdfSopenharmony_cistatic int zoo_mark(zoo_t z, char *entry);
68f08c3bdfSopenharmony_cistatic int zoo_lock(zoo_t z);
69f08c3bdfSopenharmony_cistatic int zoo_unlock(zoo_t z);
70f08c3bdfSopenharmony_ci/* cat_args(): helper function to make cmdline from argc, argv */
71f08c3bdfSopenharmony_cichar *cat_args(int argc, char **argv);
72f08c3bdfSopenharmony_ci
73f08c3bdfSopenharmony_ci/* zoo_getname(): create a filename to use for the zoo */
74f08c3bdfSopenharmony_cichar *zoo_getname(void)
75f08c3bdfSopenharmony_ci{
76f08c3bdfSopenharmony_ci	char buf[1024];
77f08c3bdfSopenharmony_ci	char *zoo;
78f08c3bdfSopenharmony_ci
79f08c3bdfSopenharmony_ci	zoo = getenv("ZOO");
80f08c3bdfSopenharmony_ci	if (zoo) {
81f08c3bdfSopenharmony_ci		snprintf(buf, 1024, "%s/%s", zoo, "active");
82f08c3bdfSopenharmony_ci		return strdup(buf);
83f08c3bdfSopenharmony_ci	} else {
84f08c3bdfSopenharmony_ci		/* if there is no environment variable, we don't know where to put it */
85f08c3bdfSopenharmony_ci		return NULL;
86f08c3bdfSopenharmony_ci	}
87f08c3bdfSopenharmony_ci}
88f08c3bdfSopenharmony_ci
89f08c3bdfSopenharmony_ci/* zoo_open(): open a zoo for use */
90f08c3bdfSopenharmony_cizoo_t zoo_open(char *zooname)
91f08c3bdfSopenharmony_ci{
92f08c3bdfSopenharmony_ci	zoo_t new_zoo;
93f08c3bdfSopenharmony_ci
94f08c3bdfSopenharmony_ci	new_zoo = (zoo_t) fopen(zooname, "r+");
95f08c3bdfSopenharmony_ci	if (!new_zoo) {
96f08c3bdfSopenharmony_ci		if (errno == ENOENT) {
97f08c3bdfSopenharmony_ci			/* file doesn't exist, try fopen(xxx, "a+") */
98f08c3bdfSopenharmony_ci			new_zoo = (zoo_t) fopen(zooname, "a+");
99f08c3bdfSopenharmony_ci			if (!new_zoo) {
100f08c3bdfSopenharmony_ci				/* total failure */
101f08c3bdfSopenharmony_ci				snprintf(zoo_error, ZELEN,
102f08c3bdfSopenharmony_ci					 "Could not open zoo as \"%s\", errno:%d %s",
103f08c3bdfSopenharmony_ci					 zooname, errno, strerror(errno));
104f08c3bdfSopenharmony_ci				return 0;
105f08c3bdfSopenharmony_ci			}
106f08c3bdfSopenharmony_ci			fclose(new_zoo);
107f08c3bdfSopenharmony_ci			new_zoo = fopen(zooname, "r+");
108f08c3bdfSopenharmony_ci		} else {
109f08c3bdfSopenharmony_ci			snprintf(zoo_error, ZELEN,
110f08c3bdfSopenharmony_ci				 "Could not open zoo as \"%s\", errno:%d %s",
111f08c3bdfSopenharmony_ci				 zooname, errno, strerror(errno));
112f08c3bdfSopenharmony_ci		}
113f08c3bdfSopenharmony_ci	}
114f08c3bdfSopenharmony_ci	return new_zoo;
115f08c3bdfSopenharmony_ci}
116f08c3bdfSopenharmony_ci
117f08c3bdfSopenharmony_ciint zoo_close(zoo_t z)
118f08c3bdfSopenharmony_ci{
119f08c3bdfSopenharmony_ci	int ret;
120f08c3bdfSopenharmony_ci
121f08c3bdfSopenharmony_ci	ret = fclose(z);
122f08c3bdfSopenharmony_ci	if (ret) {
123f08c3bdfSopenharmony_ci		snprintf(zoo_error, ZELEN,
124f08c3bdfSopenharmony_ci			 "closing zoo caused error, errno:%d %s",
125f08c3bdfSopenharmony_ci			 errno, strerror(errno));
126f08c3bdfSopenharmony_ci	}
127f08c3bdfSopenharmony_ci	return ret;
128f08c3bdfSopenharmony_ci}
129f08c3bdfSopenharmony_ci
130f08c3bdfSopenharmony_cistatic int zoo_mark(zoo_t z, char *entry)
131f08c3bdfSopenharmony_ci{
132f08c3bdfSopenharmony_ci	FILE *fp = (FILE *) z;
133f08c3bdfSopenharmony_ci	int found = 0;
134f08c3bdfSopenharmony_ci	long pos;
135f08c3bdfSopenharmony_ci	char buf[BUFLEN];
136f08c3bdfSopenharmony_ci
137f08c3bdfSopenharmony_ci	if (fp == NULL)
138f08c3bdfSopenharmony_ci		return -1;
139f08c3bdfSopenharmony_ci
140f08c3bdfSopenharmony_ci	if (zoo_lock(z))
141f08c3bdfSopenharmony_ci		return -1;
142f08c3bdfSopenharmony_ci
143f08c3bdfSopenharmony_ci	/* first fit */
144f08c3bdfSopenharmony_ci	rewind(fp);
145f08c3bdfSopenharmony_ci
146f08c3bdfSopenharmony_ci	do {
147f08c3bdfSopenharmony_ci		pos = ftell(fp);
148f08c3bdfSopenharmony_ci
149f08c3bdfSopenharmony_ci		if (fgets(buf, BUFLEN, fp) == NULL)
150f08c3bdfSopenharmony_ci			break;
151f08c3bdfSopenharmony_ci
152f08c3bdfSopenharmony_ci		if (buf[0] == '#') {
153f08c3bdfSopenharmony_ci			rewind(fp);
154f08c3bdfSopenharmony_ci			if (fseek(fp, pos, SEEK_SET)) {
155f08c3bdfSopenharmony_ci				/* error */
156f08c3bdfSopenharmony_ci				snprintf(zoo_error, ZELEN,
157f08c3bdfSopenharmony_ci					 "seek error while writing to zoo file, errno:%d %s",
158f08c3bdfSopenharmony_ci					 errno, strerror(errno));
159f08c3bdfSopenharmony_ci				return -1;
160f08c3bdfSopenharmony_ci			}
161f08c3bdfSopenharmony_ci			/* write the entry, left justified, and padded/truncated to the
162f08c3bdfSopenharmony_ci			 * same size as the previous entry */
163f08c3bdfSopenharmony_ci			fprintf(fp, "%-*.*s\n", (int)strlen(buf) - 1,
164f08c3bdfSopenharmony_ci				(int)strlen(buf) - 1, entry);
165f08c3bdfSopenharmony_ci			found = 1;
166f08c3bdfSopenharmony_ci			break;
167f08c3bdfSopenharmony_ci		}
168f08c3bdfSopenharmony_ci	} while (1);
169f08c3bdfSopenharmony_ci
170f08c3bdfSopenharmony_ci	if (!found) {
171f08c3bdfSopenharmony_ci		if (fseek(fp, 0, SEEK_END)) {
172f08c3bdfSopenharmony_ci			snprintf(zoo_error, ZELEN,
173f08c3bdfSopenharmony_ci				 "error seeking to end of zoo file, errno:%d %s",
174f08c3bdfSopenharmony_ci				 errno, strerror(errno));
175f08c3bdfSopenharmony_ci			return -1;
176f08c3bdfSopenharmony_ci		}
177f08c3bdfSopenharmony_ci		fprintf(fp, "%-*.*s\n", 79, 79, entry);
178f08c3bdfSopenharmony_ci	}
179f08c3bdfSopenharmony_ci	fflush(fp);
180f08c3bdfSopenharmony_ci
181f08c3bdfSopenharmony_ci	if (zoo_unlock(z))
182f08c3bdfSopenharmony_ci		return -1;
183f08c3bdfSopenharmony_ci	return 0;
184f08c3bdfSopenharmony_ci}
185f08c3bdfSopenharmony_ci
186f08c3bdfSopenharmony_ciint zoo_mark_cmdline(zoo_t z, pid_t p, char *tag, char *cmdline)
187f08c3bdfSopenharmony_ci{
188f08c3bdfSopenharmony_ci	char new_entry[BUFLEN];
189f08c3bdfSopenharmony_ci
190f08c3bdfSopenharmony_ci	snprintf(new_entry, 80, "%d,%s,%s", p, tag, cmdline);
191f08c3bdfSopenharmony_ci	return zoo_mark(z, new_entry);
192f08c3bdfSopenharmony_ci}
193f08c3bdfSopenharmony_ci
194f08c3bdfSopenharmony_ciint zoo_mark_args(zoo_t z, pid_t p, char *tag, int ac, char **av)
195f08c3bdfSopenharmony_ci{
196f08c3bdfSopenharmony_ci	char *cmdline;
197f08c3bdfSopenharmony_ci	int ret;
198f08c3bdfSopenharmony_ci
199f08c3bdfSopenharmony_ci	cmdline = cat_args(ac, av);
200f08c3bdfSopenharmony_ci	ret = zoo_mark_cmdline(z, p, tag, cmdline);
201f08c3bdfSopenharmony_ci
202f08c3bdfSopenharmony_ci	free(cmdline);
203f08c3bdfSopenharmony_ci	return ret;
204f08c3bdfSopenharmony_ci}
205f08c3bdfSopenharmony_ci
206f08c3bdfSopenharmony_ciint zoo_clear(zoo_t z, pid_t p)
207f08c3bdfSopenharmony_ci{
208f08c3bdfSopenharmony_ci	FILE *fp = (FILE *) z;
209f08c3bdfSopenharmony_ci	long pos;
210f08c3bdfSopenharmony_ci	char buf[BUFLEN];
211f08c3bdfSopenharmony_ci	pid_t that_pid;
212f08c3bdfSopenharmony_ci	int found = 0;
213f08c3bdfSopenharmony_ci
214f08c3bdfSopenharmony_ci	if (fp == NULL)
215f08c3bdfSopenharmony_ci		return -1;
216f08c3bdfSopenharmony_ci
217f08c3bdfSopenharmony_ci	if (zoo_lock(z))
218f08c3bdfSopenharmony_ci		return -1;
219f08c3bdfSopenharmony_ci	rewind(fp);
220f08c3bdfSopenharmony_ci
221f08c3bdfSopenharmony_ci	do {
222f08c3bdfSopenharmony_ci		pos = ftell(fp);
223f08c3bdfSopenharmony_ci
224f08c3bdfSopenharmony_ci		if (fgets(buf, BUFLEN, fp) == NULL)
225f08c3bdfSopenharmony_ci			break;
226f08c3bdfSopenharmony_ci
227f08c3bdfSopenharmony_ci		if (buf[0] == '#')
228f08c3bdfSopenharmony_ci			continue;
229f08c3bdfSopenharmony_ci
230f08c3bdfSopenharmony_ci		that_pid = atoi(buf);
231f08c3bdfSopenharmony_ci		if (that_pid == p) {
232f08c3bdfSopenharmony_ci			if (fseek(fp, pos, SEEK_SET)) {
233f08c3bdfSopenharmony_ci				/* error */
234f08c3bdfSopenharmony_ci				snprintf(zoo_error, ZELEN,
235f08c3bdfSopenharmony_ci					 "seek error while writing to zoo file, errno:%d %s",
236f08c3bdfSopenharmony_ci					 errno, strerror(errno));
237f08c3bdfSopenharmony_ci				return -1;
238f08c3bdfSopenharmony_ci			}
239f08c3bdfSopenharmony_ci			if (ftell(fp) != pos) {
240f08c3bdfSopenharmony_ci				printf("fseek failed\n");
241f08c3bdfSopenharmony_ci			}
242f08c3bdfSopenharmony_ci			fputs("#", fp);
243f08c3bdfSopenharmony_ci			found = 1;
244f08c3bdfSopenharmony_ci			break;
245f08c3bdfSopenharmony_ci		}
246f08c3bdfSopenharmony_ci	} while (1);
247f08c3bdfSopenharmony_ci
248f08c3bdfSopenharmony_ci	fflush(fp);
249f08c3bdfSopenharmony_ci
250f08c3bdfSopenharmony_ci	/* FIXME: unlock zoo file */
251f08c3bdfSopenharmony_ci	if (zoo_unlock(z))
252f08c3bdfSopenharmony_ci		return -1;
253f08c3bdfSopenharmony_ci
254f08c3bdfSopenharmony_ci	if (!found) {
255f08c3bdfSopenharmony_ci		snprintf(zoo_error, ZELEN,
256f08c3bdfSopenharmony_ci			 "zoo_clear() did not find pid(%d)", p);
257f08c3bdfSopenharmony_ci		return 1;
258f08c3bdfSopenharmony_ci	}
259f08c3bdfSopenharmony_ci	return 0;
260f08c3bdfSopenharmony_ci
261f08c3bdfSopenharmony_ci}
262f08c3bdfSopenharmony_ci
263f08c3bdfSopenharmony_cipid_t zoo_getpid(zoo_t z, char *tag)
264f08c3bdfSopenharmony_ci{
265f08c3bdfSopenharmony_ci	FILE *fp = (FILE *) z;
266f08c3bdfSopenharmony_ci	char buf[BUFLEN], *s;
267f08c3bdfSopenharmony_ci	pid_t this_pid = -1;
268f08c3bdfSopenharmony_ci
269f08c3bdfSopenharmony_ci	if (fp == NULL)
270f08c3bdfSopenharmony_ci		return -1;
271f08c3bdfSopenharmony_ci
272f08c3bdfSopenharmony_ci	if (zoo_lock(z))
273f08c3bdfSopenharmony_ci		return -1;
274f08c3bdfSopenharmony_ci
275f08c3bdfSopenharmony_ci	rewind(fp);
276f08c3bdfSopenharmony_ci	do {
277f08c3bdfSopenharmony_ci		if (fgets(buf, BUFLEN, fp) == NULL)
278f08c3bdfSopenharmony_ci			break;
279f08c3bdfSopenharmony_ci
280f08c3bdfSopenharmony_ci		if (buf[0] == '#')
281f08c3bdfSopenharmony_ci			continue;	/* recycled line */
282f08c3bdfSopenharmony_ci
283f08c3bdfSopenharmony_ci		if ((s = strchr(buf, ',')) == NULL)
284f08c3bdfSopenharmony_ci			continue;	/* line was not expected format */
285f08c3bdfSopenharmony_ci
286f08c3bdfSopenharmony_ci		if (strncmp(s + 1, tag, strlen(tag)))
287f08c3bdfSopenharmony_ci			continue;	/* tag does not match */
288f08c3bdfSopenharmony_ci
289f08c3bdfSopenharmony_ci		this_pid = atoi(buf);
290f08c3bdfSopenharmony_ci		break;
291f08c3bdfSopenharmony_ci	} while (1);
292f08c3bdfSopenharmony_ci
293f08c3bdfSopenharmony_ci	if (zoo_unlock(z))
294f08c3bdfSopenharmony_ci		return -1;
295f08c3bdfSopenharmony_ci	return this_pid;
296f08c3bdfSopenharmony_ci}
297f08c3bdfSopenharmony_ci
298f08c3bdfSopenharmony_ciint zoo_lock(zoo_t z)
299f08c3bdfSopenharmony_ci{
300f08c3bdfSopenharmony_ci	FILE *fp = (FILE *) z;
301f08c3bdfSopenharmony_ci	struct flock zlock;
302f08c3bdfSopenharmony_ci	sigset_t block_these;
303f08c3bdfSopenharmony_ci	int ret;
304f08c3bdfSopenharmony_ci
305f08c3bdfSopenharmony_ci	if (fp == NULL)
306f08c3bdfSopenharmony_ci		return -1;
307f08c3bdfSopenharmony_ci
308f08c3bdfSopenharmony_ci	zlock.l_whence = zlock.l_start = zlock.l_len = 0;
309f08c3bdfSopenharmony_ci	zlock.l_type = F_WRLCK;
310f08c3bdfSopenharmony_ci
311f08c3bdfSopenharmony_ci	sigemptyset(&block_these);
312f08c3bdfSopenharmony_ci	sigaddset(&block_these, SIGINT);
313f08c3bdfSopenharmony_ci	sigaddset(&block_these, SIGTERM);
314f08c3bdfSopenharmony_ci	sigaddset(&block_these, SIGHUP);
315f08c3bdfSopenharmony_ci	sigaddset(&block_these, SIGUSR1);
316f08c3bdfSopenharmony_ci	sigaddset(&block_these, SIGUSR2);
317f08c3bdfSopenharmony_ci	sigprocmask(SIG_BLOCK, &block_these, NULL);
318f08c3bdfSopenharmony_ci
319f08c3bdfSopenharmony_ci	do {
320f08c3bdfSopenharmony_ci		ret = fcntl(fileno(fp), F_SETLKW, &zlock);
321f08c3bdfSopenharmony_ci	} while (ret == -1 && errno == EINTR);
322f08c3bdfSopenharmony_ci
323f08c3bdfSopenharmony_ci	sigprocmask(SIG_UNBLOCK, &block_these, NULL);
324f08c3bdfSopenharmony_ci	if (ret == -1) {
325f08c3bdfSopenharmony_ci		snprintf(zoo_error, ZELEN,
326f08c3bdfSopenharmony_ci			 "failed to unlock zoo file, errno:%d %s",
327f08c3bdfSopenharmony_ci			 errno, strerror(errno));
328f08c3bdfSopenharmony_ci		return -1;
329f08c3bdfSopenharmony_ci	}
330f08c3bdfSopenharmony_ci	return 0;
331f08c3bdfSopenharmony_ci
332f08c3bdfSopenharmony_ci}
333f08c3bdfSopenharmony_ci
334f08c3bdfSopenharmony_ciint zoo_unlock(zoo_t z)
335f08c3bdfSopenharmony_ci{
336f08c3bdfSopenharmony_ci	FILE *fp = (FILE *) z;
337f08c3bdfSopenharmony_ci	struct flock zlock;
338f08c3bdfSopenharmony_ci	sigset_t block_these;
339f08c3bdfSopenharmony_ci	int ret;
340f08c3bdfSopenharmony_ci
341f08c3bdfSopenharmony_ci	if (fp == NULL)
342f08c3bdfSopenharmony_ci		return -1;
343f08c3bdfSopenharmony_ci
344f08c3bdfSopenharmony_ci	zlock.l_whence = zlock.l_start = zlock.l_len = 0;
345f08c3bdfSopenharmony_ci	zlock.l_type = F_UNLCK;
346f08c3bdfSopenharmony_ci
347f08c3bdfSopenharmony_ci	sigemptyset(&block_these);
348f08c3bdfSopenharmony_ci	sigaddset(&block_these, SIGINT);
349f08c3bdfSopenharmony_ci	sigaddset(&block_these, SIGTERM);
350f08c3bdfSopenharmony_ci	sigaddset(&block_these, SIGHUP);
351f08c3bdfSopenharmony_ci	sigaddset(&block_these, SIGUSR1);
352f08c3bdfSopenharmony_ci	sigaddset(&block_these, SIGUSR2);
353f08c3bdfSopenharmony_ci	sigprocmask(SIG_BLOCK, &block_these, NULL);
354f08c3bdfSopenharmony_ci
355f08c3bdfSopenharmony_ci	do {
356f08c3bdfSopenharmony_ci		ret = fcntl(fileno(fp), F_SETLKW, &zlock);
357f08c3bdfSopenharmony_ci	} while (ret == -1 && errno == EINTR);
358f08c3bdfSopenharmony_ci
359f08c3bdfSopenharmony_ci	sigprocmask(SIG_UNBLOCK, &block_these, NULL);
360f08c3bdfSopenharmony_ci
361f08c3bdfSopenharmony_ci	if (ret == -1) {
362f08c3bdfSopenharmony_ci		snprintf(zoo_error, ZELEN,
363f08c3bdfSopenharmony_ci			 "failed to lock zoo file, errno:%d %s",
364f08c3bdfSopenharmony_ci			 errno, strerror(errno));
365f08c3bdfSopenharmony_ci		return -1;
366f08c3bdfSopenharmony_ci	}
367f08c3bdfSopenharmony_ci	return 0;
368f08c3bdfSopenharmony_ci}
369f08c3bdfSopenharmony_ci
370f08c3bdfSopenharmony_cichar *cat_args(int argc, char **argv)
371f08c3bdfSopenharmony_ci{
372f08c3bdfSopenharmony_ci	int a, size;
373f08c3bdfSopenharmony_ci	char *cmd;
374f08c3bdfSopenharmony_ci
375f08c3bdfSopenharmony_ci	for (size = a = 0; a < argc; a++) {
376f08c3bdfSopenharmony_ci		size += strlen(argv[a]);
377f08c3bdfSopenharmony_ci		size++;
378f08c3bdfSopenharmony_ci	}
379f08c3bdfSopenharmony_ci
380f08c3bdfSopenharmony_ci	if ((cmd = malloc(size)) == NULL) {
381f08c3bdfSopenharmony_ci		snprintf(zoo_error, ZELEN,
382f08c3bdfSopenharmony_ci			 "Malloc Error, %s/%d", __FILE__, __LINE__);
383f08c3bdfSopenharmony_ci		return NULL;
384f08c3bdfSopenharmony_ci	}
385f08c3bdfSopenharmony_ci
386f08c3bdfSopenharmony_ci	*cmd = '\0';
387f08c3bdfSopenharmony_ci	for (a = 0; a < argc; a++) {
388f08c3bdfSopenharmony_ci		if (a != 0)
389f08c3bdfSopenharmony_ci			strcat(cmd, " ");
390f08c3bdfSopenharmony_ci		strcat(cmd, argv[a]);
391f08c3bdfSopenharmony_ci	}
392f08c3bdfSopenharmony_ci
393f08c3bdfSopenharmony_ci	return cmd;
394f08c3bdfSopenharmony_ci}
395f08c3bdfSopenharmony_ci
396f08c3bdfSopenharmony_ci#if defined(UNIT_TEST)
397f08c3bdfSopenharmony_ci
398f08c3bdfSopenharmony_civoid zt_add(zoo_t z, int n)
399f08c3bdfSopenharmony_ci{
400f08c3bdfSopenharmony_ci	char cmdline[200];
401f08c3bdfSopenharmony_ci	char tag[10];
402f08c3bdfSopenharmony_ci
403f08c3bdfSopenharmony_ci	snprintf(tag, 10, "%s%d", "test", n);
404f08c3bdfSopenharmony_ci	snprintf(cmdline, 200, "%s%d %s %s %s", "runtest", n, "one", "two",
405f08c3bdfSopenharmony_ci		 "three");
406f08c3bdfSopenharmony_ci
407f08c3bdfSopenharmony_ci	zoo_mark_cmdline(z, n, tag, cmdline);
408f08c3bdfSopenharmony_ci}
409f08c3bdfSopenharmony_ci
410f08c3bdfSopenharmony_ciint main(int argc, char *argv[])
411f08c3bdfSopenharmony_ci{
412f08c3bdfSopenharmony_ci
413f08c3bdfSopenharmony_ci	char *zooname;
414f08c3bdfSopenharmony_ci	zoo_t test_zoo;
415f08c3bdfSopenharmony_ci	char *test_tag = "unittest";
416f08c3bdfSopenharmony_ci	int i, j;
417f08c3bdfSopenharmony_ci
418f08c3bdfSopenharmony_ci	zooname = zoo_getname();
419f08c3bdfSopenharmony_ci
420f08c3bdfSopenharmony_ci	if (!zooname) {
421f08c3bdfSopenharmony_ci		zooname = strdup("test_zoo");
422f08c3bdfSopenharmony_ci	}
423f08c3bdfSopenharmony_ci	printf("Test zoo filename is %s\n", zooname);
424f08c3bdfSopenharmony_ci
425f08c3bdfSopenharmony_ci	if ((test_zoo = zoo_open(zooname)) == NULL) {
426f08c3bdfSopenharmony_ci		printf("Error opennning zoo\n");
427f08c3bdfSopenharmony_ci		exit(-1);
428f08c3bdfSopenharmony_ci	}
429f08c3bdfSopenharmony_ci
430f08c3bdfSopenharmony_ci	zoo_mark_args(test_zoo, getpid(), test_tag, argc, argv);
431f08c3bdfSopenharmony_ci
432f08c3bdfSopenharmony_ci	for (j = 0; j < 5; j++) {
433f08c3bdfSopenharmony_ci		for (i = 0; i < 20; i++) {
434f08c3bdfSopenharmony_ci			zt_add(test_zoo, i);
435f08c3bdfSopenharmony_ci		}
436f08c3bdfSopenharmony_ci
437f08c3bdfSopenharmony_ci		for (; i >= 0; i--) {
438f08c3bdfSopenharmony_ci			zoo_clear(test_zoo, i);
439f08c3bdfSopenharmony_ci		}
440f08c3bdfSopenharmony_ci	}
441f08c3bdfSopenharmony_ci
442f08c3bdfSopenharmony_ci	zoo_clear(test_zoo, getpid());
443f08c3bdfSopenharmony_ci
444f08c3bdfSopenharmony_ci	return 0;
445f08c3bdfSopenharmony_ci}
446f08c3bdfSopenharmony_ci
447f08c3bdfSopenharmony_ci#endif
448