10dc076565f772bb1953209fb69ea150b494aaa40robbiew/*
20dc076565f772bb1953209fb69ea150b494aaa40robbiew* Copyright (c) 2005, Bull S.A..  All rights reserved.
30dc076565f772bb1953209fb69ea150b494aaa40robbiew* Created by: Sebastien Decugis
40dc076565f772bb1953209fb69ea150b494aaa40robbiew
50dc076565f772bb1953209fb69ea150b494aaa40robbiew* This program is free software; you can redistribute it and/or modify it
60dc076565f772bb1953209fb69ea150b494aaa40robbiew* under the terms of version 2 of the GNU General Public License as
70dc076565f772bb1953209fb69ea150b494aaa40robbiew* published by the Free Software Foundation.
80dc076565f772bb1953209fb69ea150b494aaa40robbiew*
90dc076565f772bb1953209fb69ea150b494aaa40robbiew* This program is distributed in the hope that it would be useful, but
100dc076565f772bb1953209fb69ea150b494aaa40robbiew* WITHOUT ANY WARRANTY; without even the implied warranty of
110dc076565f772bb1953209fb69ea150b494aaa40robbiew* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
120dc076565f772bb1953209fb69ea150b494aaa40robbiew*
130dc076565f772bb1953209fb69ea150b494aaa40robbiew* You should have received a copy of the GNU General Public License along
14fed9641096e27f79a0f2d9adfe9839dd8d11dc0fWanlong Gao* with this program; if not, write the Free Software Foundation, Inc.,
15fed9641096e27f79a0f2d9adfe9839dd8d11dc0fWanlong Gao* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
160dc076565f772bb1953209fb69ea150b494aaa40robbiew
170dc076565f772bb1953209fb69ea150b494aaa40robbiew* This sample test aims to check the following assertion:
180dc076565f772bb1953209fb69ea150b494aaa40robbiew*
190dc076565f772bb1953209fb69ea150b494aaa40robbiew*  When the semaphore is referenced by other processes, the function has
200dc076565f772bb1953209fb69ea150b494aaa40robbiew* no effect on the state of the semaphore.
210dc076565f772bb1953209fb69ea150b494aaa40robbiew
220dc076565f772bb1953209fb69ea150b494aaa40robbiew* The steps are:
230dc076565f772bb1953209fb69ea150b494aaa40robbiew* -> Create a named semaphore
240dc076565f772bb1953209fb69ea150b494aaa40robbiew* -> create a thread which waits on the semaphore
250dc076565f772bb1953209fb69ea150b494aaa40robbiew* -> unlink the semaphore
260dc076565f772bb1953209fb69ea150b494aaa40robbiew* -> check the thread did not return
270dc076565f772bb1953209fb69ea150b494aaa40robbiew* -> post the semaphore
280dc076565f772bb1953209fb69ea150b494aaa40robbiew* -> check the thread returned
290dc076565f772bb1953209fb69ea150b494aaa40robbiew* -> close the semaphore
300dc076565f772bb1953209fb69ea150b494aaa40robbiew
310dc076565f772bb1953209fb69ea150b494aaa40robbiew* The test fails if the semaphore state is changed by sem_unlink.
320dc076565f772bb1953209fb69ea150b494aaa40robbiew
330dc076565f772bb1953209fb69ea150b494aaa40robbiew*/
340dc076565f772bb1953209fb69ea150b494aaa40robbiew
350dc076565f772bb1953209fb69ea150b494aaa40robbiew/******************************************************************************/
360dc076565f772bb1953209fb69ea150b494aaa40robbiew/*************************** standard includes ********************************/
370dc076565f772bb1953209fb69ea150b494aaa40robbiew/******************************************************************************/
380dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <pthread.h>
390dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <stdarg.h>
400dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <stdio.h>
410dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <stdlib.h>
420dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <string.h>
430dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <unistd.h>
440dc076565f772bb1953209fb69ea150b494aaa40robbiew
450dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <semaphore.h>
460dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <errno.h>
470dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <fcntl.h>
480dc076565f772bb1953209fb69ea150b494aaa40robbiew
490dc076565f772bb1953209fb69ea150b494aaa40robbiew/******************************************************************************/
500dc076565f772bb1953209fb69ea150b494aaa40robbiew/***************************   Test framework   *******************************/
510dc076565f772bb1953209fb69ea150b494aaa40robbiew/******************************************************************************/
528d9c084e1770f2719ef99a79416584c945cc775fWanlong Gao#include "../testfrmw/testfrmw.h"
538d9c084e1770f2719ef99a79416584c945cc775fWanlong Gao#include "../testfrmw/testfrmw.c"
540dc076565f772bb1953209fb69ea150b494aaa40robbiew/* This header is responsible for defining the following macros:
552c28215423293e443469a07ae7011135d058b671Garrett Cooper * UNRESOLVED(ret, descr);
562c28215423293e443469a07ae7011135d058b671Garrett Cooper *    where descr is a description of the error and ret is an int
570dc076565f772bb1953209fb69ea150b494aaa40robbiew *   (error code for example)
580dc076565f772bb1953209fb69ea150b494aaa40robbiew * FAILED(descr);
590dc076565f772bb1953209fb69ea150b494aaa40robbiew *    where descr is a short text saying why the test has failed.
600dc076565f772bb1953209fb69ea150b494aaa40robbiew * PASSED();
610dc076565f772bb1953209fb69ea150b494aaa40robbiew *    No parameter.
622c28215423293e443469a07ae7011135d058b671Garrett Cooper *
630dc076565f772bb1953209fb69ea150b494aaa40robbiew * Both three macros shall terminate the calling process.
640dc076565f772bb1953209fb69ea150b494aaa40robbiew * The testcase shall not terminate in any other maneer.
652c28215423293e443469a07ae7011135d058b671Garrett Cooper *
660dc076565f772bb1953209fb69ea150b494aaa40robbiew * The other file defines the functions
670dc076565f772bb1953209fb69ea150b494aaa40robbiew * void output_init()
680dc076565f772bb1953209fb69ea150b494aaa40robbiew * void output(char * string, ...)
692c28215423293e443469a07ae7011135d058b671Garrett Cooper *
700dc076565f772bb1953209fb69ea150b494aaa40robbiew * Those may be used to output information.
710dc076565f772bb1953209fb69ea150b494aaa40robbiew */
720dc076565f772bb1953209fb69ea150b494aaa40robbiew
730dc076565f772bb1953209fb69ea150b494aaa40robbiew/******************************************************************************/
740dc076565f772bb1953209fb69ea150b494aaa40robbiew/**************************** Configuration ***********************************/
750dc076565f772bb1953209fb69ea150b494aaa40robbiew/******************************************************************************/
760dc076565f772bb1953209fb69ea150b494aaa40robbiew#ifndef VERBOSE
770dc076565f772bb1953209fb69ea150b494aaa40robbiew#define VERBOSE 1
780dc076565f772bb1953209fb69ea150b494aaa40robbiew#endif
790dc076565f772bb1953209fb69ea150b494aaa40robbiew
800dc076565f772bb1953209fb69ea150b494aaa40robbiew#define SEM_NAME  "/sem_unlink_9_1"
810dc076565f772bb1953209fb69ea150b494aaa40robbiew
820dc076565f772bb1953209fb69ea150b494aaa40robbiew/******************************************************************************/
830dc076565f772bb1953209fb69ea150b494aaa40robbiew/***************************    Test case   ***********************************/
840dc076565f772bb1953209fb69ea150b494aaa40robbiew/******************************************************************************/
850dc076565f772bb1953209fb69ea150b494aaa40robbiewint thread_state = 0;
860dc076565f772bb1953209fb69ea150b494aaa40robbiew
87354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid *threaded(void *arg)
880dc076565f772bb1953209fb69ea150b494aaa40robbiew{
890dc076565f772bb1953209fb69ea150b494aaa40robbiew	int ret;
900dc076565f772bb1953209fb69ea150b494aaa40robbiew	thread_state = 1;
910dc076565f772bb1953209fb69ea150b494aaa40robbiew
92354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	do {
93e9410dfd93b8e415ecbe3f7e09a085462b27836eGarrett Cooper		ret = sem_wait(arg);
940dc076565f772bb1953209fb69ea150b494aaa40robbiew	}
9543088e16aa60d69e3ec5a69cdd8bdd45b8891127Garrett Cooper	while (ret != 0 && errno == EINTR);
960dc076565f772bb1953209fb69ea150b494aaa40robbiew
97354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (ret != 0) {
98e9410dfd93b8e415ecbe3f7e09a085462b27836eGarrett Cooper		UNRESOLVED(errno, "Failed to wait for the semaphore");
990dc076565f772bb1953209fb69ea150b494aaa40robbiew	}
1000dc076565f772bb1953209fb69ea150b494aaa40robbiew
1010dc076565f772bb1953209fb69ea150b494aaa40robbiew	thread_state = 2;
1020dc076565f772bb1953209fb69ea150b494aaa40robbiew	return NULL;
1030dc076565f772bb1953209fb69ea150b494aaa40robbiew}
1040dc076565f772bb1953209fb69ea150b494aaa40robbiew
1050dc076565f772bb1953209fb69ea150b494aaa40robbiew/* The main test function. */
1064ca2bbdcd3003f3c8df4e6129e9c7b2bd1514f87Cyril Hrubisint main(void)
1070dc076565f772bb1953209fb69ea150b494aaa40robbiew{
1080dc076565f772bb1953209fb69ea150b494aaa40robbiew	int ret;
1090dc076565f772bb1953209fb69ea150b494aaa40robbiew	pthread_t child;
110354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	sem_t *sem;
1110dc076565f772bb1953209fb69ea150b494aaa40robbiew
1120dc076565f772bb1953209fb69ea150b494aaa40robbiew	/* Initialize output */
1130dc076565f772bb1953209fb69ea150b494aaa40robbiew	output_init();
1140dc076565f772bb1953209fb69ea150b494aaa40robbiew
1150dc076565f772bb1953209fb69ea150b494aaa40robbiew	/* Create the semaphore */
116e9410dfd93b8e415ecbe3f7e09a085462b27836eGarrett Cooper	sem = sem_open(SEM_NAME, O_CREAT | O_EXCL, 0777, 0);
1170dc076565f772bb1953209fb69ea150b494aaa40robbiew
118354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if ((sem == SEM_FAILED) && (errno == EEXIST)) {
119e9410dfd93b8e415ecbe3f7e09a085462b27836eGarrett Cooper		sem_unlink(SEM_NAME);
120e9410dfd93b8e415ecbe3f7e09a085462b27836eGarrett Cooper		sem = sem_open(SEM_NAME, O_CREAT | O_EXCL, 0777, 0);
1210dc076565f772bb1953209fb69ea150b494aaa40robbiew	}
1220dc076565f772bb1953209fb69ea150b494aaa40robbiew
123354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (sem == SEM_FAILED) {
124e9410dfd93b8e415ecbe3f7e09a085462b27836eGarrett Cooper		UNRESOLVED(errno, "Failed to create the semaphore");
1250dc076565f772bb1953209fb69ea150b494aaa40robbiew	}
1260dc076565f772bb1953209fb69ea150b494aaa40robbiew
1270dc076565f772bb1953209fb69ea150b494aaa40robbiew	/* Create the child */
128e9410dfd93b8e415ecbe3f7e09a085462b27836eGarrett Cooper	ret = pthread_create(&child, NULL, threaded, sem);
1290dc076565f772bb1953209fb69ea150b494aaa40robbiew
130354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (ret != 0) {
131e9410dfd93b8e415ecbe3f7e09a085462b27836eGarrett Cooper		UNRESOLVED(ret, "Failed to create the thread");
1320dc076565f772bb1953209fb69ea150b494aaa40robbiew	}
1330dc076565f772bb1953209fb69ea150b494aaa40robbiew
1340dc076565f772bb1953209fb69ea150b494aaa40robbiew	/* Wait for the child to be waiting. */
135354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	while (thread_state != 1) {
1360dc076565f772bb1953209fb69ea150b494aaa40robbiew		sched_yield();
1370dc076565f772bb1953209fb69ea150b494aaa40robbiew	}
1380dc076565f772bb1953209fb69ea150b494aaa40robbiew
1390dc076565f772bb1953209fb69ea150b494aaa40robbiew	/* Unlink */
140e9410dfd93b8e415ecbe3f7e09a085462b27836eGarrett Cooper	ret = sem_unlink(SEM_NAME);
1410dc076565f772bb1953209fb69ea150b494aaa40robbiew
142354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (ret != 0) {
143e9410dfd93b8e415ecbe3f7e09a085462b27836eGarrett Cooper		UNRESOLVED(errno, "Failed to unlink the semaphore");
1440dc076565f772bb1953209fb69ea150b494aaa40robbiew	}
1450dc076565f772bb1953209fb69ea150b494aaa40robbiew
1460dc076565f772bb1953209fb69ea150b494aaa40robbiew	/* Check the semaphore state did not change. */
147e9410dfd93b8e415ecbe3f7e09a085462b27836eGarrett Cooper	sleep(1);
1480dc076565f772bb1953209fb69ea150b494aaa40robbiew
149354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (thread_state != 1) {
150e9410dfd93b8e415ecbe3f7e09a085462b27836eGarrett Cooper		FAILED("sem_unlink made sem_wait thread return");
1510dc076565f772bb1953209fb69ea150b494aaa40robbiew	}
1520dc076565f772bb1953209fb69ea150b494aaa40robbiew
1530dc076565f772bb1953209fb69ea150b494aaa40robbiew	/* Post the semaphore */
154e9410dfd93b8e415ecbe3f7e09a085462b27836eGarrett Cooper	ret = sem_post(sem);
1550dc076565f772bb1953209fb69ea150b494aaa40robbiew
156354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (ret != 0) {
157e9410dfd93b8e415ecbe3f7e09a085462b27836eGarrett Cooper		UNRESOLVED(errno, "Failed to post the semaphore");
1580dc076565f772bb1953209fb69ea150b494aaa40robbiew	}
1590dc076565f772bb1953209fb69ea150b494aaa40robbiew
1600dc076565f772bb1953209fb69ea150b494aaa40robbiew	/* Join the thread */
161e9410dfd93b8e415ecbe3f7e09a085462b27836eGarrett Cooper	ret = pthread_join(child, NULL);
1620dc076565f772bb1953209fb69ea150b494aaa40robbiew
163354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (ret != 0) {
164e9410dfd93b8e415ecbe3f7e09a085462b27836eGarrett Cooper		UNRESOLVED(ret, "Failed to join the thread");
1650dc076565f772bb1953209fb69ea150b494aaa40robbiew	}
1660dc076565f772bb1953209fb69ea150b494aaa40robbiew
1670dc076565f772bb1953209fb69ea150b494aaa40robbiew	/* Now, we can destroy all */
168e9410dfd93b8e415ecbe3f7e09a085462b27836eGarrett Cooper	ret = sem_close(sem);
1690dc076565f772bb1953209fb69ea150b494aaa40robbiew
170354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (ret != 0) {
171e9410dfd93b8e415ecbe3f7e09a085462b27836eGarrett Cooper		UNRESOLVED(errno, "Failed to close the semaphore");
1720dc076565f772bb1953209fb69ea150b494aaa40robbiew	}
1730dc076565f772bb1953209fb69ea150b494aaa40robbiew
1740dc076565f772bb1953209fb69ea150b494aaa40robbiew	/* Test passed */
1750dc076565f772bb1953209fb69ea150b494aaa40robbiew#if VERBOSE > 0
176e9410dfd93b8e415ecbe3f7e09a085462b27836eGarrett Cooper	output("Test passed\n");
1770dc076565f772bb1953209fb69ea150b494aaa40robbiew
1780dc076565f772bb1953209fb69ea150b494aaa40robbiew#endif
1790dc076565f772bb1953209fb69ea150b494aaa40robbiew	PASSED;
180ec6edca7aa42b6affd989ef91b5897f96795e40fChris Dearman}
181