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

📄 cdtest.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
 * expected data, if CD type is known. */read_data_track(toc)struct cdrom_tocentry *toc;{	struct datacon_info *info;	int lba, start, end, blocksize, nblk, maxnblk, k;	int *mark;	info = cd_datacon[cd_type];	blocksize = toc->cdte_datamode == CD_DATAMODE1 ? CDROM_MODE1_SIZE :							CDROM_MODE2_SIZE;	maxnblk = MAX_DATABUF / blocksize;	start = toc->cdte_addr.lba;		/* first logical block */	end = (toc+1)->cdte_addr.lba - 1;	/* last logical block */	/* skip gaps between certain tracks */	if (toc->cdte_track != tochdr.cdth_trk1)	{		/*		 * if data mode 1 then skip gaps on all but the last track,		 * if data mode 2 then skip only if the next track is audio.		 */		if (toc->cdte_datamode == CD_DATAMODE1)			end -= CD_POSTGAP;		else		{			if (!((toc+1)->cdte_ctrl & CDTRK_DATA))				end -= CD_POSTGAP;		}	}	if (end < start) return;	send_message(NULL,VDEBUG,"Read CD track %d (data mode %d, %d blocks)",	    toc->cdte_track,toc->cdte_datamode,(end-start+1)*percent_data/100);	/* if CD type is known then read and compare data of first block */	if (cd_type != CD_OTHER)	{		/* searching for the expected track data in table */		while (info->track != toc->cdte_track &&		       info->track != CDROM_LEADOUT) info++;		/* if found then read and compare the beginning data stream */		if (info->track == toc->cdte_track)		{			nblk = info->size / blocksize;			if (info->size % blocksize) nblk++;			send_message(NULL,VDEBUG,"Read block %d and compare %d bytes of data",start,info->size);			read_data_blocks(toc->cdte_datamode,start,nblk,blocksize);			if (bcmp(databuf,info->expect,info->size))				send_message(ERDATA,ERROR,er_datacmp,info->size,start);		}	}	/*	 * This condition allows testing a partial number of data blocks in	 * a track by changing the start and end logical block addresses.	 */	if (percent_data < 100)	{		k = end - start + 1;		nblk = k * percent_data / 100;#		ifdef SVR4		lba = abs((int)rand());#		else		lba = abs((int)random());#		endif SVR4		lba %= (k - nblk + 1);		start += lba;		end = start + nblk - 1;	}	if (read_access == RANDOM_READ)	{		send_message(NULL,VDEBUG,"Randomly read block %d thru %d",start,end);		/* allocate memory to maintain read/unread block mark */		k = (end - start) / 8 + 8;		if (!(mark = (int *)malloc((u_int)k)))			send_message(ERSYS,ERROR,er_mem,k);		bzero((char *)mark,k);		/* randomly read all blocks once */		for (k = start; k <= end; k += nblk)		{			lba  = rnd_blkpos(mark,start,end);			nblk = rnd_blkcnt(mark,start,end,lba,maxnblk);			read_data_blocks(toc->cdte_datamode,lba,nblk,blocksize);			/* if quick test then only read one chunk */			if (quick_test) break;		}		/* free mark memory */		free((char *)mark);	}	else	{		send_message(NULL,VDEBUG,"Sequentially read block %d thru %d",start,end);		/* sequential read all blocks once */		for (lba = start; lba <= end; lba += nblk)		{#			ifdef SVR4			nblk = abs((int)rand());#			else			nblk = abs((int)random());#			endif SVR4			nblk = (nblk % maxnblk) + 1;			if (nblk > (end - lba + 1))				nblk = end - lba + 1;			read_data_blocks(toc->cdte_datamode,lba,nblk,blocksize);			/* if quick test then only read one chunk */			if (quick_test) break;		}	}}/* * Function to read number of blocks at specified logical block address. */read_data_blocks(datamode,lba,nblk,blocksize)u_char datamode;int lba, nblk, blocksize;{	struct cdrom_read readinfo;	int size;	send_message(NULL,DEBUG,"Read block %d thru %d, block size %d",						lba,lba+nblk-1,blocksize);	switch (datamode)	{	case CD_DATAMODE1:		/* CD data mode 1 can be read with normal read */		size = nblk * blocksize;		if (lseek(fd,(long)(lba*blocksize),L_SET) == -1)			send_message(ERSEEK,ERROR,er_seek,lba,errmsg(errno));		if (read(fd,databuf,size) != size)			send_message(ERREAD,ERROR,er_read,size,lba,errmsg(errno));		break;	case CD_DATAMODE2:		/* CD data mode 2 can only be read thru special ioctl */		size = nblk * blocksize;		readinfo.cdread_lba = lba;		readinfo.cdread_bufaddr = databuf;		readinfo.cdread_buflen = size;		if (ioctl(fd,CDROMREADMODE2,&readinfo) < 0)			send_message(ERREAD,ERROR,er_read,size,lba,errmsg(errno));		break;	default:		send_message(ERREAD,ERROR,er_datamode,datamode);		break;	}}/* * Function returns a random logical block address that has not yet been read, * where mark is the bit stream indicating blocks that are read/unread, start * and end are the first and last block boundaries.  Function will also mark * the bit position that is selected as being read. * * Note that, rnd_blkpos() and rnd_blkcnt() are used to randomly select * all blocks, each time a random number of blocks, and each block will * be selected once. */rnd_blkpos(mark,start,end)int *mark, start, end;{	u_int count, index, bit, pos;	/* select logical block within 0 and end-start+1 boundaries */	count = end - start + 1;#	ifdef SVR4	randval = (u_int)rand();#	else	randval = (u_int)random();#	endif SVR4	pos = randval % count;	/* check if block has been read then use the next unread ones */	for (;;)	{		index = pos >> 5;		bit = pos & 31;		if (!((1 << bit) & mark[index])) break;		if (++pos >= count) pos = 0;	}	mark[index] |= (1 << bit);	/* return the random position with offset from start */	return(pos+start);}/* * Function returns a random number of contiguous blocks that are not read, * where mark is the bit stream indicating blocks that are read/unread, start * and end are the first and last logical block boundaries, lba is the current * logical block, and maxnblk is the maximum number of blocks expected to * return.  Function will also mark the returned number of bits following * bit position from lba as being read. * * Note that, rnd_blkpos() and rnd_blkcnt() are used to randomly select * all blocks, each time a random number of blocks, and each block will * be selected once. */rnd_blkcnt(mark,start,end,lba,maxnblk)int *mark, start, end, lba, maxnblk;{	u_int nblk, count, index, bit;	/* select random number of blocks based on max number of blocks */	if ((lba + maxnblk) > end) maxnblk = end - lba + 1;	count = (randval % maxnblk) + 1;	/* adjust random number of blocks to contiguous unread blocks */	lba -= start;	for (nblk = 1; nblk < count; nblk++)	{		lba++;		index = lba >> 5;		bit = lba & 31;		if ((1 << bit) & mark[index]) return(nblk);		mark[index] |= (1 << bit);	}	return(count);}/* * Function to play specified audio track. * The audio status will be checked during audio play, and a time limit * will be set for each track play according to the TOC information. */play_audio_track(toc)struct cdrom_tocentry *toc;{	struct cdrom_ti ti;	struct cdrom_subchnl subchnl;	struct cdrom_volctrl volctrl;	u_long timelimit, timestart, timeout;	struct timeval t;	timelimit = ((toc+1)->cdte_addr.lba - toc->cdte_addr.lba) / NBLOCKS_SEC;	send_message(NULL,DEBUG,"Play CD track %d (%d seconds)",toc->cdte_track,timelimit);	/* Add extra seconds for error recovery: Hai 10/24/90 */	/* Change 45 sec to 60 to avoid unnecessary restriction during  */	/* heavy system load on scsi bus. Patrick 7/24/90  */	timeout = timelimit + 600; 	/* Add timeout for play fatal */	timelimit += 60 ;	/* set audio volume control */	volctrl.channel0 = volctrl.channel1 = audio_volume;	volctrl.channel2 = volctrl.channel3 = audio_volume;	if (ioctl(fd,CDROMVOLCTRL,&volctrl) < 0)		send_message(ERIOCTL,ERROR,er_ioctl,"CDROMVOLCTRL",errmsg(errno));	/* play audio track/index */	ti.cdti_trk0 = ti.cdti_trk1 = toc->cdte_track;	ti.cdti_ind0 = ti.cdti_ind1 = MIN_INDEX;	if (ioctl(fd,CDROMPLAYTRKIND,&ti) < 0)		send_message(ERIOCTL,ERROR,er_ioctl,"CDROMPLAYTRKIND",errmsg(errno));	/* if quick test then don't need to check audio status */	if (quick_test) return;	/* wait while audio is still playing */	(void) gettimeofday(&t,(struct timezone *)0);	timestart = t.tv_sec;	do	{		(void) gettimeofday(&t,(struct timezone *)0);		sleep(3);		if (ioctl(fd,CDROMSUBCHNL,&subchnl) < 0)			send_message(ERIOCTL,ERROR,er_ioctl,"CDROMSUBCHNL",errmsg(errno));		if (subchnl.cdsc_audiostatus != CDROM_AUDIO_PLAY)			break;	} while ((t.tv_sec - timestart) <= timeout);	/* check the audio status received */	switch (subchnl.cdsc_audiostatus)	{	case CDROM_AUDIO_COMPLETED:			/* completion ok */		if((t.tv_sec - timestart) > timelimit) 			send_message(0, INFO, warn_play, t.tv_sec-timestart, timelimit, ti.cdti_trk0); 		break;	case CDROM_AUDIO_PLAY:			/* still play after time out */		send_message(ERSTATUS,ERROR,er_audioplay,timeout,ti.cdti_trk0);		break;	case CDROM_AUDIO_PAUSED:			/* pause before complete */		send_message(ERSTATUS,ERROR,er_audiostop,ti.cdti_trk0);		break;	case CDROM_AUDIO_ERROR:			/* error during play */		send_message(ERSTATUS,ERROR,er_audioerr,ti.cdti_trk0);		break;	case CDROM_AUDIO_NO_STATUS:             /* no status to return */		break;	default:				/* unknown audio status */		send_message(ERSTATUS,ERROR,er_audiostat,					subchnl.cdsc_audiostatus,ti.cdti_trk0);		break;	}}/* * Dummy clean up as required by libsdrtns.a */clean_up(){	if (cdtoc) free((char *)cdtoc);	if (databuf) free(databuf);	if (fd > 0)	{		(void)ioctl(fd,CDROMSTOP);		(void)close(fd);	}}/******************************************************************************/#ifdef	lintint errno;int quick_test;char *device_name;char *versionid;/* VARARGS0 */void send_message(){}#endif/******************************************************************************/

⌨️ 快捷键说明

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