1 based on https://github.com/dankamongmen/libdank/blob/master/libdank/compat-FreeBSD.c 2 --- usb_stream/pcm_usb_stream.c.orig 2024-06-10 09:18:39 UTC 3 +++ usb_stream/pcm_usb_stream.c 4 @@ -77,6 +77,69 @@ static pthread_mutex_t uus_mutex = PTHREAD_MUTEX_INITI 5 static struct user_usb_stream *uus; 6 static pthread_mutex_t uus_mutex = PTHREAD_MUTEX_INITIALIZER; 7 8 +#ifndef __linux__ 9 +/* 10 + * Copyright (c) 2000-2011, Nick Black et al 11 + * All rights reserved. 12 + * 13 + * Redistribution and use in source and binary forms, with or without 14 + * modification, are permitted provided that the following conditions are met: 15 + * * Redistributions of source code must retain the above copyright 16 + * notice, this list of conditions and the following disclaimer. 17 + * * Redistributions in binary form must reproduce the above copyright 18 + * notice, this list of conditions and the following disclaimer in the 19 + * documentation and/or other materials provided with the distribution. 20 + * * Neither the name of Nick Black nor the names of other contributors may 21 + * be used to endorse or promote products derived from this software 22 + * without specific prior written permission. 23 + * 24 + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 25 + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 26 + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <copyright 27 + * holder> BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 28 + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 + * POSSIBILITY OF SUCH DAMAGE. 34 + */ 35 + 36 +// This is suitable really only for use with libdank's mremap_and_ftruncate(), 37 +// due to assumptions it makes about the flags to pass to mmap(2). The only 38 +// mremap(2) use case addressed is that of MREMAP_MAYMOVE. oldaddr must be a 39 +// valid previous return from mmap(); NULL is not acceptable (ala Linux's 40 +// mremap(2)), resulting in undefined behavior, despite realloc(3) semantics. 41 +// Similarly, oldlen and newlen must be non-zero (and page-aligned). 42 +void *mremap_compat(int fd,void *oldaddr,size_t oldlen, 43 + size_t newlen,int prot,int flags){ 44 + void *ret; 45 + 46 + // From mmap(2) on freebsd 6.3: A successful FIXED mmap deletes any 47 + // previous mapping in the allocated address range. This means: 48 + // remapping over a current map will blow it away (unless FIXED isn't 49 + // provided, in which case it can't overlap an old mapping. See bug 50 + // 733 for extensive discussion of this issue for Linux and FreeBSD). 51 + if((ret = mmap((char *)oldaddr + oldlen,newlen - oldlen,prot,flags,fd,oldlen)) == MAP_FAILED){ 52 + // We couldn't get the memory whatsoever (or we were a fresh 53 + // allocation that succeeded). Return the immediate result... 54 + return ret; 55 + } // ret != MAP_FAILED. Did we squash? 56 + if(ret != (char *)oldaddr + oldlen){ 57 + // We got the memory, but not where we wanted it. Copy over the 58 + // old map, and then free it up... 59 + munmap(ret,newlen - oldlen); 60 + if((ret = mmap(NULL,newlen,prot,flags,fd,0)) == MAP_FAILED){ 61 + return ret; 62 + } 63 + memcpy(ret,oldaddr,oldlen); 64 + munmap(oldaddr,oldlen); // Free the old mapping 65 + return ret; 66 + } // We successfully squashed. Return a pointer to the first buf. 67 + return oldaddr; 68 +} 69 +#endif 70 + 71 static struct user_usb_stream *get_uus(int card) 72 { 73 pthread_mutex_lock(&uus_mutex); 74 @@ -217,7 +280,11 @@ static int snd_pcm_us_prepare(snd_pcm_ioplug_t *io) 75 } 76 77 78 +#ifdef __linux__ 79 uus->s = mremap(uus->s, sizeof(struct usb_stream), uus->s->read_size, MREMAP_MAYMOVE); 80 +#else 81 + uus->s = mremap_compat(us->pfd.fd, uus->s, sizeof(struct usb_stream), uus->s->read_size, PROT_READ, MAP_SHARED); 82 +#endif 83 if (MAP_FAILED == uus->s) { 84 perror("ALSA/USX2Y: mmap"); 85 return -EPERM; 86