/*
 *	rmsem.c - removes (presumably stale) semaphores
 *	Copyright (C) 2000 Fred Barnes
 *
 *	This program is free software; you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation; either version 2 of the License, or
 *	(at your option) any later version.
 *
 *	This program is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *
 *	You should have received a copy of the GNU General Public License
 *	along with this program; if not, write to the Free Software
 *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <errno.h>

#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
	/* union semun is defined by including <sys/sem.h> */
#else
	/* according to X/OPEN we have to define it ourselves */
	union semun {
		int val;
		struct semid_ds *buf;
		unsigned short int *array;
		struct seminfo *__buf;
	};
#endif


/*
 *	int main (int argc, char **argv)
 *	Start here
 */
int main (int argc, char **argv)
{
	int i, sem_id, errs;
	union semun sem_arg;

	if (argc < 2) {
		fprintf (stderr, "%s: attempting to delete *all* semaphores...\n", *argv);
		errs = 1;
		for (sem_id=0; sem_id<=0x7fffffff; sem_id++) {
			if (semctl (sem_id, 0, IPC_RMID, sem_arg) >= 0) {
				errs = 0;
				fprintf (stderr, "%s: removed semaphore set %d\n", *argv, sem_id);
			}
		}
	} else {
		errs = 0;
		for (i=1; i<argc; i++) {
			if (sscanf (argv[i], "%d", &sem_id) != 1) {
				fprintf (stderr, "%s: strange integer value [%s] - ignoring it.\n", *argv, argv[i]);
				errs++;
				continue;
			}
			if (semctl (sem_id, 0, IPC_RMID, sem_arg) < 0) {
				fprintf (stderr, "%s: unable to remove semaphore %d: %s\n", *argv, sem_id, strerror(errno));
				errs++;
				continue;
			}
		}
	}
	return errs ? 1 : 0;
}


