/*---------------------------------------------------------------------+
|                             cleanup ()                               |
| ==================================================================== |
|                                                                      |
| Function:  Closes all of the pipes, kills all of the child           |
|            processes and exits the program...                        |
|                                                                      |
+---------------------------------------------------------------------*/
void cleanup()
{
	int i;

	if (getpid() == parent_pid) {
		delete_semaphores();
		for (i = 0; i < num_children; i++) {
			if (pid[i] > (pid_t) 0 && kill(pid[i], SIGKILL) < 0)
				sys_error("signal failed", __LINE__);
		}
	}

	exit(-1);
}
Exemple #2
0
void sig_end_handler(int signal_number) {

    if (signal_number == SIGINT || signal_number == SIGTERM) {

        shmdt(shared_mem_ptr);
        shmctl(shmid, IPC_RMID, NULL);
        log_message("Shared memory deleted from system", LOG_DEBUG);

        delete_semaphores();

        remove_lock();
        log_message("Shutting down streams server", LOG_INFO);
        exit(EXIT_SUCCESS);
    }
}
/*---------------------------------------------------------------------+
|                               main                                   |
| ==================================================================== |
|                                                                      |
| Function:  Main program  (see prolog for more details)               |
|                                                                      |
| Returns:   (0)  Successful completion                                |
|            (-1) Error occurred                                       |
|                                                                      |
+---------------------------------------------------------------------*/
int main(int argc, char **argv)
{
	int fd;			/* Misc file descriptor  */
	int i;			/* Misc loop index */
	int shmem_size;		/* Size (in bytes) of shared memory segment */
	int status;		/* Child processes exit status */
	unsigned char *ptr;	/* Misc pointer */
	unsigned char data = 0;	/* Value written into shared memory segment */
	unsigned char *shmptr;	/* Shared memory segment address */
	unsigned long cksum;	/* Shared memory segment checksum */

	/*
	 * Parse command line arguments and print out program header
	 */
	parse_args(argc, argv);
	printf("%s: IPC Shared Memory TestSuite program\n", *argv);

	/*
	 * Setup the signal handlers (in case user aborts program).
	 *
	 * Create the semaphores to insure exclusive writes to the
	 * shared memory segment.
	 *
	 * Save the parent process id and initialize the array of child
	 * process ids.
	 */
	setup_signal_handlers();
	create_semaphores();

	parent_pid = getpid();
	for (i = 0; i < num_children; i++)
		pid[i] = (pid_t) 0;

	/*
	 * Create a shared memory segment for storing the read count
	 * (number of child processes reading shared data)
	 * After creating the shared memory segment, initialize it.
	 */
	if ((fd = open("/dev/zero", O_RDWR)) < 0)
		sys_error("open failed", __LINE__);
	if ((read_count = (int *)
	     mmap(0, sizeof(int), PROT_READ | PROT_WRITE,
		  MAP_SHARED, fd, 0)) < 0)
		sys_error("mmap failed", __LINE__);
	close(fd);
	*read_count = 0;

	/*
	 * Create a shared memory segment for storing the child
	 * processes checksums by memory mapping /dev/zero.
	 * After creating the shared memory segment, initialize it.
	 */
	if ((fd = open("/dev/zero", O_RDWR)) < 0)
		sys_error("open failed", __LINE__);
	shmem_size = sizeof(unsigned long) * num_children;
	if ((checksum = (unsigned long *)
	     mmap(0, shmem_size, PROT_READ | PROT_WRITE,
		  MAP_SHARED, fd, 0)) < 0)
		sys_error("mmap failed", __LINE__);
	close(fd);

	for (i = 0; i < num_children; i++)
		*(checksum + (sizeof(unsigned long) * i)) = 0;

	/*
	 * Create the "scratch" shared memory segment for storing
	 * a series of values by memory mapping /dev/zero.
	 */
	if ((fd = open("/dev/zero", O_RDWR)) < 0)
		sys_error("open failed", __LINE__);

	printf("\n\tGet shared memory segment (%d bytes)\n", buffer_size);
	if ((shmptr = mmap(0, buffer_size, PROT_READ | PROT_WRITE,
			   MAP_SHARED, fd, 0)) < 0)
		sys_error("mmap failed", __LINE__);
	close(fd);

	/*
	 * Obtain an exclusive "write" lock on the shared memory data
	 * segment -- get lock now to insure the parent process gets
	 * first access to the segment.
	 */
	lock_resource(WRITE);

	/*
	 * Spawn all N child processes.  Each child process will compute
	 * the checksum of the shared memory segment and will store
	 * the results in the other shared memory segment accessible
	 * by the parent.
	 */
	printf("\n\tSpawning %d child processes ... \n", num_children);
	for (i = 0; i < num_children; i++) {

		if ((pid[i] = fork()) == (pid_t) 0) {
			child(i, shmptr);
			exit(0);
		} else if (pid[i] < (pid_t) 0)
			sys_error("fork failed", __LINE__);
	}

	/*
	 * Fill the "scratch" shared memory segment up with data and
	 * compute the segments checksum.  Release "write" lock after
	 * completing so that the child processes may begin to read the
	 * data.
	 */
	printf("\n\tParent: calculate shared memory segment checksum\n");
	cksum = data = 0;

	for (ptr = shmptr; ptr < (shmptr + buffer_size); ptr++) {
		*ptr = (data++) % (UCHAR_MAX + 1);
		cksum += *ptr;
	}
	printf("\t        shared memory checksum %08lx\n", cksum);
	unlock_resource(WRITE);

	/*
	 * Wait for the child processes to compute the checksums and complete.
	 * After the processes complete, check their exit status to insure
	 * that they ran to completion and then verify the corresponding
	 * checksum.
	 */
	for (i = 0; i < num_children; i++) {
		waitpid(pid[i], &status, 0);

		if (!WIFEXITED(status))
			sys_error("child process terminated abnormally",
				  __LINE__);
		if (cksum != *(checksum + (sizeof(unsigned long) * i))) {
			printf("checksum [%d] = %08lx\n", i, checksum[i]);
			error("checksums do not match", __LINE__);
		}
	}
	printf("\n\tParent: children calculated segment successfully\n");

	/*
	 * Program completed successfully, cleanup semaphores and exit.
	 */
	delete_semaphores();
	printf("\nsuccessful!\n");

	return (0);
}