⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fifo.c

📁 刻录光盘的程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* @(#)fifo.c	1.21 99/12/29 Copyright 1989,1997 J. Schilling */#ifndef lintstatic	char sccsid[] =	"@(#)fifo.c	1.21 99/12/29 Copyright 1989,1997 J. Schilling";#endif/* *	A "fifo" that uses shared memory between two processes * *	The actual code is a mixture of borrowed code from star's fifo.c *	and a proposal from Finn Arne Gangstad <finnag@guardian.no> *	who had the idea to use a ring buffer to handle average size chunks. * *	Copyright (c) 1989,1997 J. Schilling *//* * 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, 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; see the file COPYING.  If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */#define	DEBUG/*#define	XDEBUG*/#include <mconfig.h>#if	!defined(HAVE_SMMAP) && !defined(HAVE_USGSHM) && !defined(HAVE_DOSALLOCSHAREDMEM)#undef	FIFO			/* We cannot have a FIFO on this platform */#endif#ifdef	FIFO#if !defined(USE_MMAP) && !defined(USE_USGSHM)#define	USE_MMAP#endif#ifndef	HAVE_SMMAP#	undef	USE_MMAP#	define	USE_USGSHM	/* now SYSV shared memory is the default*/#endif#ifdef	USE_MMAP		/* Only want to have one implementation */#	undef	USE_USGSHM	/* mmap() is preferred			*/#endif#ifdef	HAVE_DOSALLOCSHAREDMEM	/* This is for OS/2 */#	undef	USE_MMAP#	undef	USE_USGSHM#	define	USE_OS2SHM#endif#include <fctldefs.h>#include <sys/types.h>#if defined(HAVE_SMMAP) && defined(USE_MMAP)#include <sys/mman.h>#endif#include <stdio.h>#include <stdxlib.h>#include <unixstd.h>#include <waitdefs.h>#include <utypes.h>#include <standard.h>#include <errno.h>#include <signal.h>#include <libport.h>#include "cdrecord.h"#ifdef DEBUG#ifdef XDEBUGFILE	*ef;#define	USDEBUG1	if (debug) {if(s == owner_reader)fprintf(ef, "r");else fprintf(ef, "w");fflush(ef);}#define	USDEBUG2	if (debug) {if(s == owner_reader)fprintf(ef, "R");else fprintf(ef, "W");fflush(ef);}#else#define	USDEBUG1#define	USDEBUG2#endif#define	EDEBUG(a)	if (debug) error a#else#define	EDEBUG(a)#define	USDEBUG1#define	USDEBUG2#endif#define palign(x, a)	(((char *)(x)) + ((a) - 1 - (((unsigned)((x)-1))%(a))))typedef enum faio_owner {	owner_none,	owner_reader,	owner_writer,	owner_faio} fowner_t;char	*onames[] = {	"none",	"reader",	"writer",	"faio"};typedef struct faio {	int	len;	volatile fowner_t owner;	short	fd;	short	saved_errno;	char	*bufp;} faio_t;struct faio_stats {	long	puts;	long	gets;	long	empty;	long	full;	long	done;	long	cont_low;} *sp;#define	MIN_BUFFERS	3#define	MSECS	1000#define	SECS	(1000*MSECS)/* * Note: WRITER_MAXWAIT & READER_MAXWAIT need to be greater than the SCSI * timeout for commands that write to the media. This is currently 200s * if we are in SAO mode. *//* microsecond delay between each buffer-ready probe by writing process */#define	WRITER_DELAY	(20*MSECS)#define	WRITER_MAXWAIT	(240*SECS)	/* 240 seconds max wait for data *//* microsecond delay between each buffer-ready probe by reading process */#define	READER_DELAY	(80*MSECS)#define	READER_MAXWAIT	(240*SECS)	/* 240 seconds max wait for reader */LOCAL	char	*buf;LOCAL	char	*bufbase;LOCAL	char	*bufend;LOCAL	long	buflen;extern	int	debug;extern	int	lverbose;EXPORT	void	init_fifo	__PR((long));#ifdef	USE_MMAPLOCAL	char*	mkshare		__PR((int size));#endif#ifdef	USE_USGSHMLOCAL	char*	mkshm		__PR((int size));#endif#ifdef	USE_OS2SHMLOCAL	char*	mkos2shm	__PR((int size));#endifEXPORT	BOOL	init_faio	__PR((int tracks, track_t *track, int));EXPORT	BOOL	await_faio	__PR((void));EXPORT	void	kill_faio	__PR((void));EXPORT	int	wait_faio	__PR((void));LOCAL	void	faio_reader	__PR((int tracks, track_t *track));LOCAL	void	faio_read_track	__PR((track_t *trackp));LOCAL	void	faio_wait_on_buffer __PR((faio_t *f, fowner_t s,					  unsigned long delay,					  unsigned long max_wait));LOCAL	int	faio_read_segment __PR((int fd, faio_t *f, int len));LOCAL	faio_t	*faio_ref	__PR((int n));EXPORT	int	faio_read_buf	__PR((int f, char *bp, int size));EXPORT	int	faio_get_buf	__PR((int f, char **bpp, int size));EXPORT	void	fifo_stats	__PR((void));EXPORT	int	fifo_percent	__PR((BOOL addone));EXPORT voidinit_fifo(fs)	long	fs;{	int	pagesize;	if (fs == 0L)		return;#ifdef	_SC_PAGESIZE	pagesize = sysconf(_SC_PAGESIZE);#else	pagesize = getpagesize();#endif	buflen = roundup(fs, pagesize) + pagesize;	EDEBUG(("fs: %ld buflen: %ld\n", fs, buflen));#if	defined(USE_MMAP)	buf = mkshare(buflen);#endif#if	defined(USE_USGSHM)	buf = mkshm(buflen);#endif#if	defined(USE_OS2SHM)	buf = mkos2shm(buflen);#endif	bufbase = buf;	bufend = buf + buflen;	EDEBUG(("buf: %X bufend: %X, buflen: %ld\n", buf, bufend, buflen));	buf = palign(buf, pagesize);	buflen -= buf - bufbase;	EDEBUG(("buf: %X bufend: %X, buflen: %ld (align %ld)\n", buf, bufend, buflen, buf - bufbase));	/*	 * Dirty the whole buffer. This can die with various signals if	 * we're trying to lock too much memory	 */	fillbytes(buf, buflen, '\0');#ifdef	XDEBUG	if (debug)		ef = fopen("/tmp/ef", "w");#endif}#ifdef	USE_MMAPLOCAL char *mkshare(size)	int	size;{	int	f;	char	*addr;#ifdef	MAP_ANONYMOUS	/* HP/UX */	f = -1;	addr = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, f, 0);#else	if ((f = open("/dev/zero", O_RDWR)) < 0)		comerr("Cannot open '/dev/zero'.\n");	addr = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, f, 0);#endif	if (addr == (char *)-1)		comerr("Cannot get mmap for %d Bytes on /dev/zero.\n", size);	close(f);	if (debug) errmsgno(EX_BAD, "shared memory segment attached: %x\n", addr);	return (addr);}#endif#ifdef	USE_USGSHM#include <sys/ipc.h>#include <sys/shm.h>LOCAL char *mkshm(size)	int	size;{	int	id;	char	*addr;	/*	 * Unfortunately, a declaration of shmat() is missing in old	 * implementations such as AT&T SVr0 and SunOS.	 * We cannot add this definition here because the return-type	 * changed on newer systems.	 *	 * We will get a warning like this:	 *	 * warning: assignment of pointer from integer lacks a cast	 * or	 * warning: illegal combination of pointer and integer, op =	 *//*	extern	char *shmat();*/	if ((id = shmget(IPC_PRIVATE, size, IPC_CREAT|0600)) == -1)		comerr("shmget failed\n");	if (debug) errmsgno(EX_BAD, "shared memory segment allocated: %d\n", id);	if ((addr = shmat(id, (char *)0, 0600)) == (char *)-1)		comerr("shmat failed\n");	if (debug) errmsgno(EX_BAD, "shared memory segment attached: %x\n", addr);	if (shmctl(id, IPC_RMID, 0) < 0)		comerr("shmctl failed to detach shared memory segment\n");#ifdef	SHM_LOCK	/*	 * Although SHM_LOCK is standard, it seems that all versions of AIX	 * ommit this definition.	 */	if (shmctl(id, SHM_LOCK, 0) < 0)		comerr("shmctl failed to lock shared memory segment\n");#endif	return (addr);}#endif#ifdef	USE_OS2SHMLOCAL char *mkos2shm(size)	int	size;{	char	*addr;	/*	 * The OS/2 implementation of shm (using shm.dll) limits the size of one shared	 * memory segment to 0x3fa000 (aprox. 4MBytes). Using OS/2 native API we have	 * no such restriction so I decided to use it allowing fifos of arbitrary size.         */	if(DosAllocSharedMem(&addr,NULL,size,0X100L | 0x1L | 0x2L | 0x10L))		comerr("DosAllocSharedMem() failed\n");	if (debug)		errmsgno(EX_BAD, "shared memory allocated at address: %x\n", addr);	return (addr);}#endifLOCAL	int	faio_buffers;LOCAL	int	faio_buf_size;LOCAL	int	buf_idx;LOCAL	pid_t	faio_pid;LOCAL	BOOL	faio_didwait;/*#define	faio_ref(n)	(&((faio_t *)buf)[n])*/EXPORT BOOLinit_faio(tracks, track, bufsize)	int	tracks;	track_t	*track;	int	bufsize;{	int	n;	faio_t	*f;	int	pagesize;	char	*base;	if (buflen == 0L)		return (FALSE);#ifdef	_SC_PAGESIZE	pagesize = sysconf(_SC_PAGESIZE);#else	pagesize = getpagesize();#endif	faio_buf_size = bufsize;	f = (faio_t *)buf;	/*	 * Compute space for buffer headers.	 * Round bufsize up to pagesize to make each FIFO segment	 * properly page aligned.	 */	bufsize = roundup(bufsize, pagesize);	faio_buffers = (buflen - sizeof(*sp)) / bufsize;	EDEBUG(("bufsize: %d buffers: %d hdrsize %d\n", bufsize, faio_buffers, faio_buffers * sizeof(struct faio)));	/*	 * Reduce buffer space by header space.	 */	n = sizeof(*sp) + faio_buffers * sizeof(struct faio);	n = roundup(n, pagesize);	faio_buffers = (buflen-n) / bufsize;	EDEBUG(("bufsize: %d buffers: %d hdrsize %d\n", bufsize, faio_buffers, faio_buffers * sizeof(struct faio)));	if (faio_buffers < MIN_BUFFERS) {		errmsgno(EX_BAD,			"write-buffer too small, minimum is %dk. Disabling.\n",						MIN_BUFFERS*bufsize/1024);		return (FALSE);	}	if (debug)		printf("Using %d buffers of %d bytes.\n", faio_buffers, faio_buf_size);	f = (faio_t *)buf;	base = buf + roundup(sizeof(*sp) + faio_buffers * sizeof(struct faio),				pagesize);	for (n = 0; n < faio_buffers; n++, f++, base += bufsize) {		/* Give all the buffers to the reader process */		f->owner = owner_writer;		f->bufp = base;		f->fd = -1;	}	sp = (struct faio_stats *)f;	/* point past headers */	sp->gets = sp->puts = sp->done = 0L;	faio_pid = fork();	if (faio_pid < 0)		comerr("fork(2) failed");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -