try using normal read/write is mmap() fails. tell the VM system we are going to be doing sequential access via madvise().
This commit is contained in:
parent
ff5615a44f
commit
dcd2624f5e
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: play.c,v 1.8 1999/04/02 16:05:55 augustss Exp $ */
|
||||
/* $NetBSD: play.c,v 1.9 1999/04/13 07:21:45 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999 Matthew R. Green
|
||||
@ -47,6 +47,7 @@
|
||||
|
||||
int main __P((int, char *[]));
|
||||
void usage __P((void));
|
||||
void play_fd __P((int, char *));
|
||||
ssize_t audioctl_write_fromhdr __P((void *, size_t, int));
|
||||
|
||||
audio_info_t info;
|
||||
@ -61,16 +62,17 @@ int precision;
|
||||
int channels;
|
||||
|
||||
char const *play_errstring = NULL;
|
||||
size_t bufsize;
|
||||
int audiofd, ctlfd;
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
size_t len, bufsize;
|
||||
ssize_t hdrlen;
|
||||
size_t len;
|
||||
off_t filesize;
|
||||
int ch, audiofd, ctlfd;
|
||||
int ch;
|
||||
int iflag = 0;
|
||||
int qflag = 0;
|
||||
int verbose = 0;
|
||||
@ -160,11 +162,11 @@ main(argc, argv)
|
||||
|
||||
audiofd = open(device, O_WRONLY);
|
||||
#ifdef _PATH_OAUDIO
|
||||
/* Allow the non-unit device to be used. */
|
||||
if (audiofd < 0 && device == _PATH_AUDIO) {
|
||||
device = _PATH_OAUDIO;
|
||||
ctldev = _PATH_OAUDIOCTL;
|
||||
audiofd = open(device, O_WRONLY);
|
||||
/* Allow the non-unit device to be used. */
|
||||
if (audiofd < 0 && device == _PATH_AUDIO) {
|
||||
device = _PATH_OAUDIO;
|
||||
ctldev = _PATH_OAUDIOCTL;
|
||||
audiofd = open(device, O_WRONLY);
|
||||
}
|
||||
#endif
|
||||
if (audiofd < 0)
|
||||
@ -185,6 +187,8 @@ main(argc, argv)
|
||||
void *addr, *oaddr;
|
||||
|
||||
do {
|
||||
ssize_t hdrlen;
|
||||
|
||||
fd = open(*argv, O_RDONLY);
|
||||
if (fd < 0)
|
||||
err(1, "could not open %s", *argv);
|
||||
@ -195,12 +199,30 @@ main(argc, argv)
|
||||
|
||||
oaddr = addr = mmap(0, (size_t)filesize, PROT_READ,
|
||||
MAP_SHARED, fd, 0);
|
||||
if (addr == (void *)-1)
|
||||
err(1, "could not mmap %s", *argv);
|
||||
|
||||
/*
|
||||
* if we failed to mmap the file, try to read it
|
||||
* instead, so that filesystems, etc, that do not
|
||||
* support mmap() work
|
||||
*/
|
||||
if (addr == (void *)-1) {
|
||||
play_fd(fd, *argv);
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* give the VM system a bit of a hint about the type
|
||||
* of accesses we will make.
|
||||
*/
|
||||
if (madvise(addr, filesize, MADV_SEQUENTIAL) < 0)
|
||||
warn("madvise failed, ignoring");
|
||||
|
||||
/*
|
||||
* get the header length and set up the audio device
|
||||
*/
|
||||
if ((hdrlen = audioctl_write_fromhdr(addr,
|
||||
(size_t)filesize, ctlfd)) < 0) {
|
||||
play_error:
|
||||
if (play_errstring)
|
||||
errx(1, "%s: %s", play_errstring, *argv);
|
||||
else
|
||||
@ -219,7 +241,8 @@ play_error:
|
||||
if (write(audiofd, addr, (size_t)filesize) != (ssize_t)filesize)
|
||||
err(1, "final write failed");
|
||||
|
||||
ioctl(audiofd, AUDIO_DRAIN);
|
||||
if (ioctl(audiofd, AUDIO_DRAIN) < 0)
|
||||
warn("audio drain ioctl failed");
|
||||
if (munmap(oaddr, (size_t)filesize) < 0)
|
||||
err(1, "munmap failed");
|
||||
|
||||
@ -227,47 +250,65 @@ play_error:
|
||||
|
||||
} while (*++argv);
|
||||
} else {
|
||||
char *buffer = malloc(bufsize);
|
||||
int n, m;
|
||||
|
||||
if (buffer == NULL)
|
||||
err(1, "malloc of read buffer failed");
|
||||
|
||||
n = read(STDIN_FILENO, buffer, bufsize);
|
||||
|
||||
if (n < 0)
|
||||
err(1, "read of standard input failed");
|
||||
if (n == 0)
|
||||
errx(1, "EOF on standard input");
|
||||
|
||||
hdrlen = audioctl_write_fromhdr(buffer, n, ctlfd);
|
||||
if (hdrlen < 0)
|
||||
goto play_error;
|
||||
|
||||
/* advance the buffer if we have to */
|
||||
if (hdrlen > 0) {
|
||||
/* shouldn't happen */
|
||||
if (hdrlen > n)
|
||||
err(1, "bogus hdrlen %d > length %d?", (int)hdrlen, n);
|
||||
|
||||
memmove(buffer, buffer + hdrlen, n - hdrlen);
|
||||
|
||||
m = read(STDIN_FILENO, buffer + n, hdrlen);
|
||||
n += m;
|
||||
}
|
||||
/* read until EOF or error */
|
||||
do {
|
||||
if (n == -1)
|
||||
err(1, "read of standard input failed");
|
||||
if (write(audiofd, buffer, n) != n)
|
||||
err(1, "write failed");
|
||||
} while ((n = read(STDIN_FILENO, buffer, bufsize)));
|
||||
ioctl(audiofd, AUDIO_DRAIN);
|
||||
play_fd(STDIN_FILENO, "standard input");
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* play the file on on the file descriptor fd
|
||||
*/
|
||||
void
|
||||
play_fd(fd, file)
|
||||
int fd;
|
||||
char *file;
|
||||
{
|
||||
char *buffer = malloc(bufsize);
|
||||
ssize_t hdrlen;
|
||||
int n, m;
|
||||
|
||||
if (buffer == NULL)
|
||||
err(1, "malloc of read buffer failed");
|
||||
|
||||
n = read(fd, buffer, bufsize);
|
||||
|
||||
if (n < 0)
|
||||
err(1, "read of standard input failed");
|
||||
if (n == 0)
|
||||
errx(1, "EOF on standard input");
|
||||
|
||||
hdrlen = audioctl_write_fromhdr(buffer, n, ctlfd);
|
||||
if (hdrlen < 0) {
|
||||
if (play_errstring)
|
||||
errx(1, "%s: %s", play_errstring, file);
|
||||
else
|
||||
errx(1, "unknown audio file: %s", file);
|
||||
}
|
||||
|
||||
/* advance the buffer if we have to */
|
||||
if (hdrlen > 0) {
|
||||
/* shouldn't happen */
|
||||
if (hdrlen > n)
|
||||
err(1, "bogus hdrlen %d > length %d?", (int)hdrlen, n);
|
||||
|
||||
memmove(buffer, buffer + hdrlen, n - hdrlen);
|
||||
|
||||
m = read(fd, buffer + n, hdrlen);
|
||||
n += m;
|
||||
}
|
||||
/* read until EOF or error */
|
||||
do {
|
||||
if (n == -1)
|
||||
err(1, "read of standard input failed");
|
||||
if (write(audiofd, buffer, n) != n)
|
||||
err(1, "write failed");
|
||||
} while ((n = read(fd, buffer, bufsize)));
|
||||
|
||||
if (ioctl(audiofd, AUDIO_DRAIN) < 0)
|
||||
warn("audio drain ioctl failed");
|
||||
}
|
||||
|
||||
/*
|
||||
* only support sun and wav audio files so far ...
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user