示例#1
0
文件: mcdx.c 项目: Einheri/wl500g
static int mcdx_transfer(struct s_drive_stuff *stuffp,
	      char *p, int sector, int nr_sectors)
/*	This seems to do the actually transfer.  But it does more.  It
	keeps track of errors occurred and will (if possible) fall back
	to single speed on error.
	Return:	-1 on timeout or other error
			else status byte (as in stuff->st) */
{
	int ans;

	ans = mcdx_xfer(stuffp, p, sector, nr_sectors);
	return ans;
#ifdef FALLBACK
	if (-1 == ans)
		stuffp->readerrs++;
	else
		return ans;

	if (stuffp->readerrs && stuffp->readcmd == READ1X) {
		xwarn("XXX Already reading 1x -- no chance\n");
		return -1;
	}

	xwarn("XXX Fallback to 1x\n");

	stuffp->readcmd = READ1X;
	return mcdx_transfer(stuffp, p, sector, nr_sectors);
#endif

}
示例#2
0
NetSocket* TCPNetworkEngine::connect(const char* uri)
{
	if(strncmp(uri, "yc://", 5) == 0)
	{
		const char* host = uri + 5;

		TCPNetSocket* s = new TCPNetSocket();
		s->socket = socket(PF_INET, SOCK_STREAM, 0);

		xerror(s->socket != SOCKET_ERROR, "Could not create a socket.");

		struct hostent* hostaddr = gethostbyname(host);
		xwarn(hostaddr->h_addr_list, "Could not retreive address for host %s", host);
		if(!hostaddr->h_addr_list)
			return NULL;

		struct sockaddr_in saddr;
		bzero(&saddr, sizeof(saddr));
		saddr.sin_family = hostaddr->h_addrtype;
		saddr.sin_port = htons(port);
#ifndef WIN32
		inet_pton(hostaddr->h_addrtype, hostaddr->h_addr_list[0], &saddr.sin_addr);
#else
		struct sockaddr_storage ss;
		int sslen = sizeof(ss);
		WSAStringToAddressA(hostaddr->h_addr_list[0], hostaddr->h_addrtype, NULL, (struct sockaddr*)&ss, &sslen);
		saddr.sin_addr = ((struct sockaddr_in *)&ss)->sin_addr;
#endif

		if(::connect(s->socket, (struct sockaddr *)&saddr, sizeof(saddr) ) == SOCKET_ERROR)
		{
			xwarn(false, "Could not connect to %s", host);
			return NULL;
		}

#ifdef WIN32
		ULONG on=1;
		ioctlsocket(s->socket, FIONBIO, &on);
#else
		fcntl(s->socket, F_SETFL, O_NONBLOCK);
#endif

		return s;
	} else {
		xwarn(false, "Unknown protocol : %s", uri);
		return NULL;
	}
}
static void __exit mcdx_exit(void)
{
	int i;

	xinfo("cleanup_module called\n");

	for (i = 0; i < MCDX_NDRIVES; i++) {
		struct s_drive_stuff *stuffp = mcdx_stuffp[i];
		if (!stuffp)
			continue;
		del_gendisk(stuffp->disk);
		if (unregister_cdrom(&stuffp->info)) {
			printk(KERN_WARNING "Can't unregister cdrom mcdx\n");
			continue;
		}
		put_disk(stuffp->disk);
		release_region(stuffp->wreg_data, MCDX_IO_SIZE);
		free_irq(stuffp->irq, NULL);
		if (stuffp->toc) {
			xtrace(MALLOC, "cleanup_module() free toc @ %p\n",
			       stuffp->toc);
			kfree(stuffp->toc);
		}
		xtrace(MALLOC, "cleanup_module() free stuffp @ %p\n",
		       stuffp);
		mcdx_stuffp[i] = NULL;
		kfree(stuffp);
	}

	if (unregister_blkdev(MAJOR_NR, "mcdx") != 0) {
		xwarn("cleanup() unregister_blkdev() failed\n");
	}
	blk_cleanup_queue(mcdx_queue);
#if !MCDX_QUIET
	else
示例#4
0
void __exit mcdx_exit(void)
{
    int i;

	xinfo("cleanup_module called\n");

    for (i = 0; i < MCDX_NDRIVES; i++) {
		struct s_drive_stuff *stuffp;
        	if (unregister_cdrom(&mcdx_info)) {
			printk(KERN_WARNING "Can't unregister cdrom mcdx\n");
			return;
		}
		stuffp = mcdx_stuffp[i];
		if (!stuffp) continue;
		release_region((unsigned long) stuffp->wreg_data, MCDX_IO_SIZE);
		free_irq(stuffp->irq, NULL);
		if (stuffp->toc) {
			xtrace(MALLOC, "cleanup_module() free toc @ %p\n", stuffp->toc);
			kfree(stuffp->toc);
		}
		xtrace(MALLOC, "cleanup_module() free stuffp @ %p\n", stuffp);
		mcdx_stuffp[i] = NULL;
		kfree(stuffp);
    }

    if (devfs_unregister_blkdev(MAJOR_NR, "mcdx") != 0) {
        xwarn("cleanup() unregister_blkdev() failed\n");
    }
	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
#if !MCDX_QUIET
	else xinfo("cleanup() succeeded\n");
示例#5
0
void State::setControlledObject(Controllable* newControlledObject, int controllerID) {
	xwarn(true, "No GC for Controllable.");
	if(controlledObjects.size() <= (unsigned int)controllerID) {
		controlledObjects.resize(controllerID+1, NULL);
	}
	controlledObjects[controllerID] = newControlledObject;
}
示例#6
0
文件: mcdx.c 项目: Einheri/wl500g
static int
mcdx_playmsf(struct s_drive_stuff *stuffp, const struct cdrom_msf *msf)
{
	unsigned char cmd[7] = {
		0, 0, 0, 0, 0, 0, 0
	};

	if (!stuffp->readcmd) {
		xinfo("Can't play from missing disk.\n");
		return -1;
	}

	cmd[0] = stuffp->playcmd;

	cmd[1] = msf->cdmsf_min0;
	cmd[2] = msf->cdmsf_sec0;
	cmd[3] = msf->cdmsf_frame0;
	cmd[4] = msf->cdmsf_min1;
	cmd[5] = msf->cdmsf_sec1;
	cmd[6] = msf->cdmsf_frame1;

	xtrace(PLAYMSF, "ioctl(): play %x "
	       "%02x:%02x:%02x -- %02x:%02x:%02x\n",
	       cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6]);

	outsb(stuffp->wreg_data, cmd, sizeof cmd);

	if (-1 == mcdx_getval(stuffp, 3 * HZ, 0, NULL)) {
		xwarn("playmsf() timeout\n");
		return -1;
	}

	stuffp->audiostatus = CDROM_AUDIO_PLAY;
	return 0;
}
void SubScriptable::freeScript() {
	xwarn(isFinished(), "Trying to forcefully unload a running script : %s.", scriptSource?scriptSource->name():"Unknown script"); // Protect from dead pointer. Not fully secure, but better than nothing.

	if(scriptSource) {
		scriptContext->engine()->scriptMap().freeScript(scriptSource);
		delete scriptSource;
	}
}
示例#8
0
文件: mcdx.c 项目: Einheri/wl500g
static int __init mcdx_init(void)
{
	int drive;
	xwarn("Version 2.14(hs) \n");

	xwarn("$Id: mcdx.c,v 1.21 1997/01/26 07:12:59 davem Exp $\n");

	/* zero the pointer array */
	for (drive = 0; drive < MCDX_NDRIVES; drive++)
		mcdx_stuffp[drive] = NULL;

	/* do the initialisation */
	for (drive = 0; drive < MCDX_NDRIVES; drive++) {
		switch (mcdx_init_drive(drive)) {
		case 2:
			return -EIO;
		case 1:
			break;
		}
	}
	return 0;
}
示例#9
0
文件: mcdx.c 项目: smx-smx/dsl-n55u
static int __init mcdx_init(void)
{
	int drive;
	xwarn("Version 2.14(hs) \n");

	xwarn("$Id: //BBN_Linux/Branch/Branch_for_SDK_Release_MultiChip_20111013/tclinux_phoenix/linux/drivers/cdrom/mcdx.c#1 $\n");

	/* zero the pointer array */
	for (drive = 0; drive < MCDX_NDRIVES; drive++)
		mcdx_stuffp[drive] = NULL;

	/* do the initialisation */
	for (drive = 0; drive < MCDX_NDRIVES; drive++) {
		switch (mcdx_init_drive(drive)) {
		case 2:
			return -EIO;
		case 1:
			break;
		}
	}
	return 0;
}
示例#10
0
GameMap* State::loadMap(VFS::File* xmlFile) {
	ScriptableObject* obj = load(xmlFile);
	GameMap* m = scriptable_object_cast<GameMap*> (obj);
	if(m != NULL) {
		// Object is a map.
		switchMap(m);
	} else {
		// Object is not a map.
		if(obj != NULL) {
			// Destroy it.
			xwarn(obj, "Trying to load a non-map object as a map.");
			delete obj;
		}
	}

	return m;
}
示例#11
0
Collidable* State::loadToMap(VFS::File* xmlFile) {
	ScriptableObject* obj = load(xmlFile);
	Collidable* c = scriptable_object_cast<Collidable*> (obj);
	if(c != NULL) {
		// Object is a Collidable.
		m_map->addObject(c);
		m_map->own(c);
	} else {
		// Object is not a Collidable.
		if(obj != NULL) {
			// Destroy it.
			xwarn(obj, "Trying to load a non-collidable object into the map.");
			delete obj;
		}
	}

	return c;
}
示例#12
0
static void
mcdx_intr(int irq, void *dev_id, struct pt_regs* regs)
{
    struct s_drive_stuff *stuffp;
	unsigned char b;

    stuffp = mcdx_irq_map[irq];

    if (stuffp == NULL ) {
		xwarn("mcdx: no device for intr %d\n", irq);
		return;
    }

#ifdef AK2
	if ( !stuffp->busy && stuffp->pending )
		stuffp->int_err = 1;

#endif /* AK2 */
	/* get the interrupt status */
	b = inb((unsigned int) stuffp->rreg_status);
	stuffp->introk = ~b & MCDX_RBIT_DTEN;

	/* NOTE: We only should get interrupts if the data we
	 * requested are ready to transfer.
	 * But the drive seems to generate ``asynchronous'' interrupts
	 * on several error conditions too.  (Despite the err int enable
	 * setting during initialisation) */

	/* if not ok, read the next byte as the drives status */
	if (!stuffp->introk) {
		xtrace(IRQ, "intr() irq %d hw status 0x%02x\n", irq, b);
		if (~b & MCDX_RBIT_STEN) {
			xinfo(  "intr() irq %d    status 0x%02x\n",
					irq, inb((unsigned int) stuffp->rreg_data));
		} else {
			xinfo(  "intr() irq %d ambiguous hw status\n", irq);
		}
	} else {
		xtrace(IRQ, "irq() irq %d ok, status %02x\n", irq, b);
    }

    stuffp->busy = 0;
    wake_up_interruptible(&stuffp->busyq);
}
示例#13
0
// QC:G
ObjectMold* Factory::createMold(TiXmlElement *xmlData, VFS::File* xmlFile)
{
	Factory::moldmapping::iterator it;

	if(!xmlData) {
		return NULL;
	}

	const char* id = xmlData->Attribute("id");

	const char* src = xmlData->Attribute("src");
	if(src) {
		std::map<const char*, const char*> overrides;
		TiXmlAttribute* attr = xmlData->FirstAttribute();
		while(attr) {
			if(strcmp(attr->Name(), "id")!=0 && strcmp(attr->Name(), "src")!=0) {
				overrides[attr->Name()] = attr->Value();
			}
			attr = attr->Next();
		}

		VFS::File* srcFile = VFS::openFile(src, xmlFile);
		ObjectMold* createdObject = loadMold(srcFile, &overrides);
		delete srcFile;

		return createdObject;
	}

	// Find the factory for this class and call it.
	it = moldFactories.find(xmlData->Value());
	xassert(it != moldFactories.end(), "Don't know how to make molds of %s", xmlData->Value());
	xassert(it->second, "NULL mold factory for class %s", xmlData->Value());

	// Call the class-specific factory
	ObjectMold* createdObject = (this->*(it->second))(xmlData, xmlFile);
	createdObject->sourceFile = xmlFile->copy();
	if(id) {
		createdObject->setObjectId(id);
	}

	xwarn(createdObject, "Warning : could not create an instance of %s", xmlData->Value() );

	return createdObject;
}
示例#14
0
文件: expand.c 项目: tizzybec/minix
static size_t
expand(char *buf, const char *execname, int what, size_t bl)
{
#ifdef __minix
	return 0;
#else
	const char *p, *ep;
	char *bp = buf;
	size_t len;
	char name[32];

	switch (what) {
	case 0:	/* HWCAP XXX: Not yet */
	case 1:	/* ISALIST XXX: Not yet */
		return 0;

	case 2:	/* ORIGIN */
		if (execname == NULL)
			xerr(1, "execname not specified in AUX vector");
		if ((ep = strrchr(p = execname, '/')) == NULL)
			xerr(1, "bad execname `%s' in AUX vector", execname);
		break;

	case 3:	/* OSNAME */
	case 4:	/* OSREL */
	case 5:	/* PLATFORM */
		len = sizeof(name);	
		if (sysctl(mib[what - 3], 2, name, &len, NULL, 0) == -1) {
			xwarn("sysctl");
			return 0;
		}
		ep = (p = name) + len - 1;
		break;
	default:
		return 0;
	}

	while (p != ep && bl)
		*bp++ = *p++, bl--;

	return bp - buf;
#endif
}
示例#15
0
UFB_Image *UFB_CreateImageFromFile(const char *filename)
{
    UFB_ImageType type = UFB_GuessImageTypeFromExt(filename);

    switch(type)
    {
        case UFB_IT_TGA:
            return UFB_CreateImageFromFileTGA(filename);

        case UFB_IT_PNG:
            return UFB_CreateImageFromFilePNG(filename);

        case UFB_IT_JPEG:
            return UFB_CreateImageFromFileJPEG(filename);

        default:
            xwarn("Could not guess image type from filename '%s'", filename);
            return NULL;
    }
}
// QC:G
size_t VorbisPCMSource::read(void* outputBuffer, size_t outputBufferLen) {
	// TODO : implement loop
	char* buf = (char*) outputBuffer;
	size_t totalBytes = 0;
	while(outputBufferLen && !eofReached) {
		long bytes = ov_read(&of, buf, outputBufferLen, 0, 2, 1, &section);
		if(bytes == OV_HOLE
		|| bytes == OV_EBADLINK
		|| bytes == OV_EINVAL) {
			xwarn(false, "Problem while reading %s.", f->name());
			return 0;
		} else if(bytes == 0) {
			eofReached = true;
			return 0;
		}
		totalBytes += bytes;
		outputBufferLen -= bytes;
		buf += bytes;
	}
	return totalBytes;
}
示例#17
0
UFB_Image *UFB_CreateImageFromFileTGA(const char *filename)
{
    TGA_Image tgaimg = TGA_LoadFromFile(filename);

    xassert(tgaimg.error == 0, "Error loading tga image '%s'", filename);

    if(tgaimg.yorigin == 0)
        xwarn("Tga image will be flipped, save with origin at upper-left corner!");

    UFB_Image *img;

    if(tgaimg.bpp == 32)
    {
        img = UFB_ConvertRGBA32PixelsToImage(tgaimg.data, tgaimg.width, tgaimg.height);
    }
    else if(tgaimg.bpp == 24)
    {
        img = UFB_ConvertRGB24PixelsToImage(tgaimg.data, tgaimg.width, tgaimg.height);
    }

    free(tgaimg.data);

    return img;
}
示例#18
0
文件: mcdx.c 项目: Einheri/wl500g
static int mcdx_xfer(struct s_drive_stuff *stuffp,
		     char *p, int sector, int nr_sectors)
/*	This does actually the transfer from the drive.
	Return:	-1 on timeout or other error
			else status byte (as in stuff->st) */
{
	int border;
	int done = 0;
	long timeout;

	if (stuffp->audio) {
		xwarn("Attempt to read from audio CD.\n");
		return -1;
	}

	if (!stuffp->readcmd) {
		xinfo("Can't transfer from missing disk.\n");
		return -1;
	}

	while (stuffp->lock) {
		interruptible_sleep_on(&stuffp->lockq);
	}

	if (stuffp->valid && (sector >= stuffp->pending)
	    && (sector < stuffp->low_border)) {

		/* All (or at least a part of the sectors requested) seems
		   * to be already requested, so we don't need to bother the
		   * drive with new requests ...
		   * Wait for the drive become idle, but first
		   * check for possible occurred errors --- the drive
		   * seems to report them asynchronously */


		border = stuffp->high_border < (border =
						sector + nr_sectors)
		    ? stuffp->high_border : border;

		stuffp->lock = current->pid;

		do {

			while (stuffp->busy) {

				timeout =
				    interruptible_sleep_on_timeout
				    (&stuffp->busyq, 5 * HZ);

				if (!stuffp->introk) {
					xtrace(XFER,
					       "error via interrupt\n");
				} else if (!timeout) {
					xtrace(XFER, "timeout\n");
				} else if (signal_pending(current)) {
					xtrace(XFER, "signal\n");
				} else
					continue;

				stuffp->lock = 0;
				stuffp->busy = 0;
				stuffp->valid = 0;

				wake_up_interruptible(&stuffp->lockq);
				xtrace(XFER, "transfer() done (-1)\n");
				return -1;
			}

			/* check if we need to set the busy flag (as we
			 * expect an interrupt */
			stuffp->busy = (3 == (stuffp->pending & 3));

			/* Test if it's the first sector of a block,
			 * there we have to skip some bytes as we read raw data */
			if (stuffp->xa && (0 == (stuffp->pending & 3))) {
				const int HEAD =
				    CD_FRAMESIZE_RAW - CD_XA_TAIL -
				    CD_FRAMESIZE;
				insb(stuffp->rreg_data, p, HEAD);
			}

			/* now actually read the data */
			insb(stuffp->rreg_data, p, 512);

			/* test if it's the last sector of a block,
			 * if so, we have to handle XA special */
			if ((3 == (stuffp->pending & 3)) && stuffp->xa) {
				char dummy[CD_XA_TAIL];
				insb(stuffp->rreg_data, &dummy[0], CD_XA_TAIL);
			}

			if (stuffp->pending == sector) {
				p += 512;
				done++;
				sector++;
			}
		} while (++(stuffp->pending) < border);

		stuffp->lock = 0;
		wake_up_interruptible(&stuffp->lockq);

	} else {

		/* The requested sector(s) is/are out of the
		 * already requested range, so we have to bother the drive
		 * with a new request. */

		static unsigned char cmd[] = {
			0,
			0, 0, 0,
			0, 0, 0
		};

		cmd[0] = stuffp->readcmd;

		/* The numbers held in ->pending, ..., should be valid */
		stuffp->valid = 1;
		stuffp->pending = sector & ~3;

		/* do some sanity checks */
		if (stuffp->pending > stuffp->lastsector) {
			xwarn
			    ("transfer() sector %d from nirvana requested.\n",
			     stuffp->pending);
			stuffp->status = MCDX_ST_EOM;
			stuffp->valid = 0;
			xtrace(XFER, "transfer() done (-1)\n");
			return -1;
		}

		if ((stuffp->low_border = stuffp->pending + DIRECT_SIZE)
		    > stuffp->lastsector + 1) {
			xtrace(XFER, "cut low_border\n");
			stuffp->low_border = stuffp->lastsector + 1;
		}
		if ((stuffp->high_border = stuffp->pending + REQUEST_SIZE)
		    > stuffp->lastsector + 1) {
			xtrace(XFER, "cut high_border\n");
			stuffp->high_border = stuffp->lastsector + 1;
		}

		{		/* Convert the sector to be requested to MSF format */
			struct cdrom_msf0 pending;
			log2msf(stuffp->pending / 4, &pending);
			cmd[1] = pending.minute;
			cmd[2] = pending.second;
			cmd[3] = pending.frame;
		}

		cmd[6] =
		    (unsigned
		     char) ((stuffp->high_border - stuffp->pending) / 4);
		xtrace(XFER, "[%2d]\n", cmd[6]);

		stuffp->busy = 1;
		/* Now really issue the request command */
		outsb(stuffp->wreg_data, cmd, sizeof cmd);

	}
#ifdef AK2
	if (stuffp->int_err) {
		stuffp->valid = 0;
		stuffp->int_err = 0;
		return -1;
	}
#endif				/* AK2 */

	stuffp->low_border = (stuffp->low_border +=
			      done) <
	    stuffp->high_border ? stuffp->low_border : stuffp->high_border;

	return done;
}
示例#19
0
文件: slabtop.c 项目: gs0622/procps
int main(int argc, char *argv[])
{
	int o;
	unsigned short old_rows;
	struct slab_info *slab_list = NULL;
	int run_once = 0, retval = EXIT_SUCCESS;

	static const struct option longopts[] = {
		{ "delay",	required_argument, NULL, 'd' },
		{ "sort",	required_argument, NULL, 's' },
		{ "once",	no_argument,	   NULL, 'o' },
		{ "help",	no_argument,	   NULL, 'h' },
		{ "version",	no_argument,	   NULL, 'V' },
		{  NULL, 0, NULL, 0 }
	};

#ifdef HAVE_PROGRAM_INVOCATION_NAME
	program_invocation_name = program_invocation_short_name;
#endif
	setlocale (LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
	atexit(close_stdout);

	sort_func = DEF_SORT_FUNC;

	while ((o = getopt_long(argc, argv, "d:s:ohV", longopts, NULL)) != -1) {
		switch (o) {
		case 'd':
			errno = 0;
			delay = strtol_or_err(optarg, _("illegal delay"));
			if (delay < 1)
				xerrx(EXIT_FAILURE,
					_("delay must be positive integer"));
			break;
		case 's':
			sort_func = (int (*)(const struct slab_info*,
				const struct slab_info *)) set_sort_func(optarg[0]);
			break;
		case 'o':
			run_once=1;
			delay = 0;
			break;
		case 'V':
			printf(PROCPS_NG_VERSION);
			return EXIT_SUCCESS;
		case 'h':
			usage(stdout);
		default:
			usage(stderr);
		}
	}

	if (tcgetattr(STDIN_FILENO, &saved_tty) == -1)
		xwarn(_("terminal setting retrieval"));

	old_rows = rows;
	term_size(0);
	if (!run_once) {
		initscr();
		resizeterm(rows, cols);
		signal(SIGWINCH, term_size);
	}
	signal(SIGINT, sigint_handler);

	do {
		struct slab_info *curr;
		struct slab_stat stats;
		struct timeval tv;
		fd_set readfds;
		char c;
		int i;
		memset(&stats, 0, sizeof(struct slab_stat));

		if (get_slabinfo(&slab_list, &stats)) {
			retval = EXIT_FAILURE;
			break;
		}

		if (!run_once && old_rows != rows) {
			resizeterm(rows, cols);
			old_rows = rows;
		}

		move(0, 0);
		print_line(" %-35s: %d / %d (%.1f%%)\n"
		       " %-35s: %d / %d (%.1f%%)\n"
		       " %-35s: %d / %d (%.1f%%)\n"
		       " %-35s: %.2fK / %.2fK (%.1f%%)\n"
		       " %-35s: %.2fK / %.2fK / %.2fK\n\n",
		       /* Translation Hint: Next five strings must not
			* exceed 35 length in characters.  */
		       /* xgettext:no-c-format */
		       _("Active / Total Objects (% used)"),
		       stats.nr_active_objs, stats.nr_objs,
		       100.0 * stats.nr_active_objs / stats.nr_objs,
	               /* xgettext:no-c-format */
		       _("Active / Total Slabs (% used)"),
		       stats.nr_active_slabs, stats.nr_slabs,
		       100.0 * stats.nr_active_slabs / stats.nr_slabs,
	               /* xgettext:no-c-format */
		       _("Active / Total Caches (% used)"),
		       stats.nr_active_caches, stats.nr_caches,
		       100.0 * stats.nr_active_caches / stats.nr_caches,
	               /* xgettext:no-c-format */
		       _("Active / Total Size (% used)"),
		       stats.active_size / 1024.0, stats.total_size / 1024.0,
		       100.0 * stats.active_size / stats.total_size,
		       _("Minimum / Average / Maximum Object"),
		       stats.min_obj_size / 1024.0, stats.avg_obj_size / 1024.0,
		       stats.max_obj_size / 1024.0);

		slab_list = slabsort(slab_list);

		attron(A_REVERSE);
		/* Translation Hint: Please keep alignment of the
		 * following intact. */
		print_line("%-78s\n", _("  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME"));
		attroff(A_REVERSE);

		curr = slab_list;
		for (i = 0; i < rows - 8 && curr->next; i++) {
			print_line("%6u %6u %3u%% %7.2fK %6u %8u %9uK %-23s\n",
				curr->nr_objs, curr->nr_active_objs, curr->use,
				curr->obj_size / 1024.0, curr->nr_slabs,
				curr->objs_per_slab, (unsigned)(curr->cache_size / 1024),
				curr->name);
			curr = curr->next;
		}

		put_slabinfo(slab_list);
		if (!run_once) {
			refresh();
			FD_ZERO(&readfds);
			FD_SET(STDIN_FILENO, &readfds);
			tv.tv_sec = delay;
			tv.tv_usec = 0;
			if (select(STDOUT_FILENO, &readfds, NULL, NULL, &tv) > 0) {
				if (read(STDIN_FILENO, &c, 1) != 1)
					break;
				parse_input(c);
			}
		}
	} while (delay);

	tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_tty);
	free_slabinfo(slab_list);
	if (!run_once)
		endwin();
	return retval;
}
示例#20
0
ScriptMap::~ScriptMap() {
	for(std::map<VFS::File*, ScriptMap::Script, strCmp>::iterator si = scripts.begin(); si != scripts.end(); si++) {
		syslog(" Script : %s", si->first->name());
	}
	xwarn(scripts.size() == 0, "Script map not empty : script allocation has memory leaks.");
}
示例#21
0
// QC:A
ScriptableObject* Factory::createInstance(TiXmlElement *xmlData, VFS::File* xmlFile, ownedset* owned)
{
	Factory::mapping::iterator it;

	if(!xmlData) {
		return NULL;
	}

	const char* id = xmlData->Attribute("id");
	if(id) {
		ScriptableObject* obj = state->script()->getobj(id);
		if(obj) {
			syslog("reusing id=%s", id);
			return obj;
		}
	}

	const char* src = xmlData->Attribute("src");
	if(src) {
		std::map<const char*, const char*> overrides;
		TiXmlAttribute* attr = xmlData->FirstAttribute();
		while(attr) {
			if(strcmp(attr->Name(), "id")!=0 && strcmp(attr->Name(), "src")!=0) {
				overrides[attr->Name()] = attr->Value();
			}
			attr = attr->Next();
		}

		VFS::File* srcFile = VFS::openFile(src, xmlFile);
		ScriptableObject* createdObject = load(srcFile, &overrides, owned);
		delete srcFile;
		
		if(id) {
			state->script()->setval(id, createdObject);
		}

		return createdObject;
	}

	// Find the factory for this class and call it.
	it = factories.find(xmlData->Value());
	xassert(it != factories.end(), "Don't know how to make instances of %s", xmlData->Value());
	xassert(it->second, "NULL factory for class %s", xmlData->Value());

	// Call the class-specific factory
	ScriptableObject* createdObject = (this->*(it->second))(xmlData, xmlFile, owned);
	createdObject->sourceFile = xmlFile->copy();
	if(id) {
		state->script()->setval(id, createdObject);
	}

	xwarn(createdObject, "Warning : could not create an instance of %s", xmlData->Value() );

#ifdef KEEP_AOD_SOURCES
	createdObject->aodSource = xmlData->Clone()->ToElement();
	char ptrValue[64];
	sprintf(ptrValue, "%p", createdObject);
	createdObject->aodSource->SetAttribute("_ptr", ptrValue);
#endif
	return createdObject;
}
示例#22
0
文件: mcdx.c 项目: Einheri/wl500g
static int __init mcdx_init_drive(int drive)
{
	struct s_version version;
	struct gendisk *disk;
	struct s_drive_stuff *stuffp;
	int size = sizeof(*stuffp);
	char msg[80];

	xtrace(INIT, "init() try drive %d\n", drive);

	xtrace(INIT, "kmalloc space for stuffpt's\n");
	xtrace(MALLOC, "init() malloc %d bytes\n", size);
	if (!(stuffp = kzalloc(size, GFP_KERNEL))) {
		xwarn("init() malloc failed\n");
		return 1;
	}

	disk = alloc_disk(1);
	if (!disk) {
		xwarn("init() malloc failed\n");
		kfree(stuffp);
		return 1;
	}

	xtrace(INIT, "init() got %d bytes for drive stuff @ %p\n",
	       sizeof(*stuffp), stuffp);

	/* set default values */
	stuffp->present = 0;	/* this should be 0 already */
	stuffp->toc = NULL;	/* this should be NULL already */

	/* setup our irq and i/o addresses */
	stuffp->irq = irq(mcdx_drive_map[drive]);
	stuffp->wreg_data = stuffp->rreg_data = port(mcdx_drive_map[drive]);
	stuffp->wreg_reset = stuffp->rreg_status = stuffp->wreg_data + 1;
	stuffp->wreg_hcon = stuffp->wreg_reset + 1;
	stuffp->wreg_chn = stuffp->wreg_hcon + 1;

	init_waitqueue_head(&stuffp->busyq);
	init_waitqueue_head(&stuffp->lockq);
	init_waitqueue_head(&stuffp->sleepq);

	/* check if i/o addresses are available */
	if (!request_region(stuffp->wreg_data, MCDX_IO_SIZE, "mcdx")) {
		xwarn("0x%03x,%d: Init failed. "
		      "I/O ports (0x%03x..0x%03x) already in use.\n",
		      stuffp->wreg_data, stuffp->irq,
		      stuffp->wreg_data,
		      stuffp->wreg_data + MCDX_IO_SIZE - 1);
		xtrace(MALLOC, "init() free stuffp @ %p\n", stuffp);
		kfree(stuffp);
		put_disk(disk);
		xtrace(INIT, "init() continue at next drive\n");
		return 0;	/* next drive */
	}

	xtrace(INIT, "init() i/o port is available at 0x%03x\n"
	       stuffp->wreg_data);
	xtrace(INIT, "init() hardware reset\n");
	mcdx_reset(stuffp, HARD, 1);

	xtrace(INIT, "init() get version\n");
	if (-1 == mcdx_requestversion(stuffp, &version, 4)) {
		/* failed, next drive */
		release_region(stuffp->wreg_data, MCDX_IO_SIZE);
		xwarn("%s=0x%03x,%d: Init failed. Can't get version.\n",
		      MCDX, stuffp->wreg_data, stuffp->irq);
		xtrace(MALLOC, "init() free stuffp @ %p\n", stuffp);
		kfree(stuffp);
		put_disk(disk);
		xtrace(INIT, "init() continue at next drive\n");
		return 0;
	}

	switch (version.code) {
	case 'D':
		stuffp->readcmd = READ2X;
		stuffp->present = DOUBLE | DOOR | MULTI;
		break;
	case 'F':
		stuffp->readcmd = READ1X;
		stuffp->present = SINGLE | DOOR | MULTI;
		break;
	case 'M':
		stuffp->readcmd = READ1X;
		stuffp->present = SINGLE;
		break;
	default:
		stuffp->present = 0;
		break;
	}

	stuffp->playcmd = READ1X;

	if (!stuffp->present) {
		release_region(stuffp->wreg_data, MCDX_IO_SIZE);
		xwarn("%s=0x%03x,%d: Init failed. No Mitsumi CD-ROM?.\n",
		      MCDX, stuffp->wreg_data, stuffp->irq);
		kfree(stuffp);
		put_disk(disk);
		return 0;	/* next drive */
	}

	xtrace(INIT, "init() register blkdev\n");
	if (register_blkdev(MAJOR_NR, "mcdx")) {
		release_region(stuffp->wreg_data, MCDX_IO_SIZE);
		kfree(stuffp);
		put_disk(disk);
		return 1;
	}

	mcdx_queue = blk_init_queue(do_mcdx_request, &mcdx_lock);
	if (!mcdx_queue) {
		unregister_blkdev(MAJOR_NR, "mcdx");
		release_region(stuffp->wreg_data, MCDX_IO_SIZE);
		kfree(stuffp);
		put_disk(disk);
		return 1;
	}

	xtrace(INIT, "init() subscribe irq and i/o\n");
	if (request_irq(stuffp->irq, mcdx_intr, IRQF_DISABLED, "mcdx", stuffp)) {
		release_region(stuffp->wreg_data, MCDX_IO_SIZE);
		xwarn("%s=0x%03x,%d: Init failed. Can't get irq (%d).\n",
		      MCDX, stuffp->wreg_data, stuffp->irq, stuffp->irq);
		stuffp->irq = 0;
		blk_cleanup_queue(mcdx_queue);
		kfree(stuffp);
		put_disk(disk);
		return 0;
	}

	xtrace(INIT, "init() get garbage\n");
	{
		int i;
		mcdx_delay(stuffp, HZ / 2);
		for (i = 100; i; i--)
			(void) inb(stuffp->rreg_status);
	}


#ifdef WE_KNOW_WHY
	/* irq 11 -> channel register */
	outb(0x50, stuffp->wreg_chn);
#endif

	xtrace(INIT, "init() set non dma but irq mode\n");
	mcdx_config(stuffp, 1);

	stuffp->info.ops = &mcdx_dops;
	stuffp->info.speed = 2;
	stuffp->info.capacity = 1;
	stuffp->info.handle = stuffp;
	sprintf(stuffp->info.name, "mcdx%d", drive);
	disk->major = MAJOR_NR;
	disk->first_minor = drive;
	strcpy(disk->disk_name, stuffp->info.name);
	disk->fops = &mcdx_bdops;
	disk->flags = GENHD_FL_CD;
	stuffp->disk = disk;

	sprintf(msg, " mcdx: Mitsumi CD-ROM installed at 0x%03x, irq %d."
		" (Firmware version %c %x)\n",
		stuffp->wreg_data, stuffp->irq, version.code, version.ver);
	mcdx_stuffp[drive] = stuffp;
	xtrace(INIT, "init() mcdx_stuffp[%d] = %p\n", drive, stuffp);
	if (register_cdrom(&stuffp->info) != 0) {
		printk("Cannot register Mitsumi CD-ROM!\n");
		free_irq(stuffp->irq, NULL);
		release_region(stuffp->wreg_data, MCDX_IO_SIZE);
		kfree(stuffp);
		put_disk(disk);
		if (unregister_blkdev(MAJOR_NR, "mcdx") != 0)
			xwarn("cleanup() unregister_blkdev() failed\n");
		blk_cleanup_queue(mcdx_queue);
		return 2;
	}
	disk->private_data = stuffp;
	disk->queue = mcdx_queue;
	add_disk(disk);
	printk(msg);
	return 0;
}
static int mcdx_open(struct cdrom_device_info *cdi, int purpose)
{
	struct s_drive_stuff *stuffp;
	xtrace(OPENCLOSE, "open()\n");
	stuffp = cdi->handle;
	if (!stuffp->present)
		return -ENXIO;

	/* Make the modules looking used ... (thanx bjorn).
	 * But we shouldn't forget to decrement the module counter
	 * on error return */

	/* this is only done to test if the drive talks with us */
	if (-1 == mcdx_getstatus(stuffp, 1))
		return -EIO;

	if (stuffp->xxx) {

		xtrace(OPENCLOSE, "open() media changed\n");
		stuffp->audiostatus = CDROM_AUDIO_INVALID;
		stuffp->readcmd = 0;
		xtrace(OPENCLOSE, "open() Request multisession info\n");
		if (-1 ==
		    mcdx_requestmultidiskinfo(stuffp, &stuffp->multi, 6))
			xinfo("No multidiskinfo\n");
	} else {
		/* multisession ? */
		if (!stuffp->multi.multi)
			stuffp->multi.msf_last.second = 2;

		xtrace(OPENCLOSE, "open() MS: %d, last @ %02x:%02x.%02x\n",
		       stuffp->multi.multi,
		       stuffp->multi.msf_last.minute,
		       stuffp->multi.msf_last.second,
		       stuffp->multi.msf_last.frame);

		{;
		}		/* got multisession information */
		/* request the disks table of contents (aka diskinfo) */
		if (-1 == mcdx_requesttocdata(stuffp, &stuffp->di, 1)) {

			stuffp->lastsector = -1;

		} else {

			stuffp->lastsector = (CD_FRAMESIZE / 512)
			    * msf2log(&stuffp->di.msf_leadout) - 1;

			xtrace(OPENCLOSE,
			       "open() start %d (%02x:%02x.%02x) %d\n",
			       stuffp->di.n_first,
			       stuffp->di.msf_first.minute,
			       stuffp->di.msf_first.second,
			       stuffp->di.msf_first.frame,
			       msf2log(&stuffp->di.msf_first));
			xtrace(OPENCLOSE,
			       "open() last %d (%02x:%02x.%02x) %d\n",
			       stuffp->di.n_last,
			       stuffp->di.msf_leadout.minute,
			       stuffp->di.msf_leadout.second,
			       stuffp->di.msf_leadout.frame,
			       msf2log(&stuffp->di.msf_leadout));
		}

		if (stuffp->toc) {
			xtrace(MALLOC, "open() free old toc @ %p\n",
			       stuffp->toc);
			kfree(stuffp->toc);

			stuffp->toc = NULL;
		}

		xtrace(OPENCLOSE, "open() init irq generation\n");
		if (-1 == mcdx_config(stuffp, 1))
			return -EIO;
#ifdef FALLBACK
		/* Set the read speed */
		xwarn("AAA %x AAA\n", stuffp->readcmd);
		if (stuffp->readerrs)
			stuffp->readcmd = READ1X;
		else
			stuffp->readcmd =
			    stuffp->present | SINGLE ? READ1X : READ2X;
		xwarn("XXX %x XXX\n", stuffp->readcmd);
#else
		stuffp->readcmd =
		    stuffp->present | SINGLE ? READ1X : READ2X;
#endif

		/* try to get the first sector, iff any ... */
		if (stuffp->lastsector >= 0) {
			char buf[512];
			int ans;
			int tries;

			stuffp->xa = 0;
			stuffp->audio = 0;

			for (tries = 6; tries; tries--) {

				stuffp->introk = 1;

				xtrace(OPENCLOSE, "open() try as %s\n",
				       stuffp->xa ? "XA" : "normal");
				/* set data mode */
				if (-1 == (ans = mcdx_setdatamode(stuffp,
								  stuffp->
								  xa ?
								  MODE2 :
								  MODE1,
								  1))) {
					/* return -EIO; */
					stuffp->xa = 0;
					break;
				}

				if ((stuffp->audio = e_audio(ans)))
					break;

				while (0 ==
				       (ans =
					mcdx_transfer(stuffp, buf, 0, 1)));

				if (ans == 1)
					break;
				stuffp->xa = !stuffp->xa;
			}
		}
		/* xa disks will be read in raw mode, others not */
		if (-1 == mcdx_setdrivemode(stuffp,
					    stuffp->xa ? RAW : COOKED,
					    1))
			return -EIO;
		if (stuffp->audio) {
			xinfo("open() audio disk found\n");
		} else if (stuffp->lastsector >= 0) {
			xinfo("open() %s%s disk found\n",
			      stuffp->xa ? "XA / " : "",
			      stuffp->multi.
			      multi ? "Multi Session" : "Single Session");
		}
	}
	stuffp->xxx = 0;
	stuffp->users++;
	return 0;
}
static void do_mcdx_request(request_queue_t * q)
{
	struct s_drive_stuff *stuffp;
	struct request *req;

      again:

	req = elv_next_request(q);
	if (!req)
		return;

	stuffp = req->rq_disk->private_data;

	if (!stuffp->present) {
		xwarn("do_request(): bad device: %s\n",req->rq_disk->disk_name);
		xtrace(REQUEST, "end_request(0): bad device\n");
		end_request(req, 0);
		return;
	}

	if (stuffp->audio) {
		xwarn("do_request() attempt to read from audio cd\n");
		xtrace(REQUEST, "end_request(0): read from audio\n");
		end_request(req, 0);
		return;
	}

	xtrace(REQUEST, "do_request() (%lu + %lu)\n",
	       req->sector, req->nr_sectors);

	if (req->cmd != READ) {
		xwarn("do_request(): non-read command to cd!!\n");
		xtrace(REQUEST, "end_request(0): write\n");
		end_request(req, 0);
		return;
	}
	else {
		stuffp->status = 0;
		while (req->nr_sectors) {
			int i;

			i = mcdx_transfer(stuffp,
					  req->buffer,
					  req->sector,
					  req->nr_sectors);

			if (i == -1) {
				end_request(req, 0);
				goto again;
			}
			req->sector += i;
			req->nr_sectors -= i;
			req->buffer += (i * 512);
		}
		end_request(req, 1);
		goto again;

		xtrace(REQUEST, "end_request(1)\n");
		end_request(req, 1);
	}

	goto again;
}
示例#25
0
文件: mcdx.c 项目: Einheri/wl500g
int mcdx_readtoc(struct s_drive_stuff *stuffp)
/*  Read the toc entries from the CD,
 *  Return: -1 on failure, else 0 */
{

	if (stuffp->toc) {
		xtrace(READTOC, "ioctl() toc already read\n");
		return 0;
	}

	xtrace(READTOC, "ioctl() readtoc for %d tracks\n",
	       stuffp->di.n_last - stuffp->di.n_first + 1);

	if (-1 == mcdx_hold(stuffp, 1))
		return -1;

	xtrace(READTOC, "ioctl() tocmode\n");
	if (-1 == mcdx_setdrivemode(stuffp, TOC, 1))
		return -EIO;

	/* all seems to be ok so far ... malloc */
	{
		int size;
		size =
		    sizeof(struct s_subqcode) * (stuffp->di.n_last -
						 stuffp->di.n_first + 2);

		xtrace(MALLOC, "ioctl() malloc %d bytes\n", size);
		stuffp->toc = kmalloc(size, GFP_KERNEL);
		if (!stuffp->toc) {
			xwarn("Cannot malloc %d bytes for toc\n", size);
			mcdx_setdrivemode(stuffp, DATA, 1);
			return -EIO;
		}
	}

	/* now read actually the index */
	{
		int trk;
		int retries;

		for (trk = 0;
		     trk < (stuffp->di.n_last - stuffp->di.n_first + 1);
		     trk++)
			stuffp->toc[trk].index = 0;

		for (retries = 300; retries; retries--) {	/* why 300? */
			struct s_subqcode q;
			unsigned int idx;

			if (-1 == mcdx_requestsubqcode(stuffp, &q, 1)) {
				mcdx_setdrivemode(stuffp, DATA, 1);
				return -EIO;
			}

			idx = bcd2uint(q.index);

			if ((idx > 0)
			    && (idx <= stuffp->di.n_last)
			    && (q.tno == 0)
			    && (stuffp->toc[idx - stuffp->di.n_first].
				index == 0)) {
				stuffp->toc[idx - stuffp->di.n_first] = q;
				xtrace(READTOC,
				       "ioctl() toc idx %d (trk %d)\n",
				       idx, trk);
				trk--;
			}
			if (trk == 0)
				break;
		}
		memset(&stuffp->
		       toc[stuffp->di.n_last - stuffp->di.n_first + 1], 0,
		       sizeof(stuffp->toc[0]));
		stuffp->toc[stuffp->di.n_last - stuffp->di.n_first +
			    1].dt = stuffp->di.msf_leadout;
	}

	/* unset toc mode */
	xtrace(READTOC, "ioctl() undo toc mode\n");
	if (-1 == mcdx_setdrivemode(stuffp, DATA, 2))
		return -EIO;

#if MCDX_DEBUG && READTOC
	{
		int trk;
		for (trk = 0;
		     trk < (stuffp->di.n_last - stuffp->di.n_first + 2);
		     trk++)
			xtrace(READTOC, "ioctl() %d readtoc %02x %02x %02x"
			       "  %02x:%02x.%02x  %02x:%02x.%02x\n",
			       trk + stuffp->di.n_first,
			       stuffp->toc[trk].control,
			       stuffp->toc[trk].tno,
			       stuffp->toc[trk].index,
			       stuffp->toc[trk].tt.minute,
			       stuffp->toc[trk].tt.second,
			       stuffp->toc[trk].tt.frame,
			       stuffp->toc[trk].dt.minute,
			       stuffp->toc[trk].dt.second,
			       stuffp->toc[trk].dt.frame);
	}
#endif

	return 0;
}
static int mcdx_talk(struct s_drive_stuff *stuffp,
	  const unsigned char *cmd, size_t cmdlen,
	  void *buffer, size_t size, unsigned int timeout, int tries)
/* Send a command to the drive, wait for the result.
 * returns -1 on timeout, drive status otherwise
 * If buffer is not zero, the result (length size) is stored there.
 * If buffer is zero the size should be the number of bytes to read
 * from the drive.  These bytes are discarded.
 */
{
	int st;
	char c;
	int discard;

	/* Somebody wants the data read? */
	if ((discard = (buffer == NULL)))
		buffer = &c;

	while (stuffp->lock) {
		xtrace(SLEEP, "*** talk: lockq\n");
		interruptible_sleep_on(&stuffp->lockq);
		xtrace(SLEEP, "talk: awoken\n");
	}

	stuffp->lock = 1;

	/* An operation other then reading data destroys the
	   * data already requested and remembered in stuffp->request, ... */
	stuffp->valid = 0;

#if MCDX_DEBUG & TALK
	{
		unsigned char i;
		xtrace(TALK,
		       "talk() %d / %d tries, res.size %d, command 0x%02x",
		       tries, timeout, size, (unsigned char) cmd[0]);
		for (i = 1; i < cmdlen; i++)
			xtrace(TALK, " 0x%02x", cmd[i]);
		xtrace(TALK, "\n");
	}
#endif

	/*  give up if all tries are done (bad) or if the status
	 *  st != -1 (good) */
	for (st = -1; st == -1 && tries; tries--) {

		char *bp = (char *) buffer;
		size_t sz = size;

		outsb(stuffp->wreg_data, cmd, cmdlen);
		xtrace(TALK, "talk() command sent\n");

		/* get the status byte */
		if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) {
			xinfo("talk() %02x timed out (status), %d tr%s left\n",
			     cmd[0], tries - 1, tries == 2 ? "y" : "ies");
			continue;
		}
		st = *bp;
		sz--;
		if (!discard)
			bp++;

		xtrace(TALK, "talk() got status 0x%02x\n", st);

		/* command error? */
		if (e_cmderr(st)) {
			xwarn("command error cmd = %02x %s \n",
			      cmd[0], cmdlen > 1 ? "..." : "");
			st = -1;
			continue;
		}

		/* audio status? */
		if (stuffp->audiostatus == CDROM_AUDIO_INVALID)
			stuffp->audiostatus =
			    e_audiobusy(st) ? CDROM_AUDIO_PLAY :
			    CDROM_AUDIO_NO_STATUS;
		else if (stuffp->audiostatus == CDROM_AUDIO_PLAY
			 && e_audiobusy(st) == 0)
			stuffp->audiostatus = CDROM_AUDIO_COMPLETED;

		/* media change? */
		if (e_changed(st)) {
			xinfo("talk() media changed\n");
			stuffp->xxx = stuffp->yyy = 1;
		}

		/* now actually get the data */
		while (sz--) {
			if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) {
				xinfo("talk() %02x timed out (data), %d tr%s left\n",
				     cmd[0], tries - 1,
				     tries == 2 ? "y" : "ies");
				st = -1;
				break;
			}
			if (!discard)
				bp++;
			xtrace(TALK, "talk() got 0x%02x\n", *(bp - 1));
		}
	}

#if !MCDX_QUIET
	if (!tries && st == -1)
		xinfo("talk() giving up\n");
#endif

	stuffp->lock = 0;
	wake_up_interruptible(&stuffp->lockq);

	xtrace(TALK, "talk() done with 0x%02x\n", st);
	return st;
}
示例#27
0
void
_rtld_process_hints(const char *execname, Search_Path **path_p,
    Library_Xform **lib_p, const char *fname)
{
	int fd;
	char *buf, small[128];
	const char *b, *ep, *ptr;
	struct stat st;
	ssize_t sz;
	Search_Path **head_p = path_p;

	if ((fd = open(fname, O_RDONLY)) == -1) {
		/* Don't complain */
		return;
	}

	/* Try to avoid mmap/stat on the file. */
	buf = small;
	buf[0] = '\0';
	sz = read(fd, buf, sizeof(small));
	if (sz == -1) {
		xwarn("read: %s", fname);
		(void)close(fd);
		return;
	}
	if (sz >= sizeof(small)) {
		if (fstat(fd, &st) == -1) {
			/* Complain */
			xwarn("fstat: %s", fname);
			(void)close(fd);
			return;
		}

		sz = (ssize_t) st.st_size;

		buf = mmap(0, sz, PROT_READ, MAP_SHARED|MAP_FILE, fd, 0);
		if (buf == MAP_FAILED) {
			xwarn("mmap: %s", fname);
			(void)close(fd);
			return;
		}
	}
	(void)close(fd);

	while ((*path_p) != NULL)
		path_p = &(*path_p)->sp_next;

	for (b = buf, ep = buf + sz; b < ep; b++) {
		(void)getcstr(&b, ep, WS);
		if (b == ep)
			break;

		ptr = getstr(&b, ep, "\n#");
		if (*ptr == '/') {
			/*
			 * Since '/' != '\n' and != '#', we know ptr <
			 * b.  And we will stop when b[-1] == '/'.
			 */
			while (b[-1] == ' ' || b[-1] == '\t')
				b--;
			path_p = _rtld_append_path(head_p, path_p, execname,
			    ptr, b);
		} else
			_rtld_process_mapping(lib_p, ptr, b);

		/*
		 * b points one of ' ', \t, \n, # or equal to ep.  So,
		 * make sure we are at newline or end of string.
		 */
		(void)getstr(&b, ep, "\n");
	}

	if (buf != small)
		(void)munmap(buf, sz);
}