diff options
| author | Pierre Ossman <ossman@cendio.se> | 2007-06-11 11:22:30 +0000 | 
|---|---|---|
| committer | Pierre Ossman <ossman@cendio.se> | 2007-06-11 11:22:30 +0000 | 
| commit | 14cbbe1096ef10091a0073009a3c65eb13d2da27 (patch) | |
| tree | 9e91ac3793f2947422dbe4ebd32dfdf33536c16a /src | |
| parent | 13a4c5290a5a80025c72e9f40c28c2e6437c82e8 (diff) | |
Support stat() and friends as some programs (audacity) likes to check if
the device node is there first.
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1467 fefdeb5f-60dc-0310-8127-8f9354f1896f
Diffstat (limited to 'src')
| -rw-r--r-- | src/utils/padsp.c | 196 | 
1 files changed, 196 insertions, 0 deletions
diff --git a/src/utils/padsp.c b/src/utils/padsp.c index b9c26f09..9a2bad44 100644 --- a/src/utils/padsp.c +++ b/src/utils/padsp.c @@ -116,9 +116,17 @@ static int (*_ioctl)(int, int, void*) = NULL;  static int (*_close)(int) = NULL;  static int (*_open)(const char *, int, mode_t) = NULL;  static FILE* (*_fopen)(const char *path, const char *mode) = NULL; +static int (*_stat)(const char *, struct stat *) = NULL; +#ifdef _STAT_VER +static int (*___xstat)(int, const char *, struct stat *) = NULL; +#endif  #ifdef HAVE_OPEN64  static int (*_open64)(const char *, int, mode_t) = NULL;  static FILE* (*_fopen64)(const char *path, const char *mode) = NULL; +static int (*_stat64)(const char *, struct stat64 *) = NULL; +#ifdef _STAT_VER +static int (*___xstat64)(int, const char *, struct stat64 *) = NULL; +#endif  #endif  static int (*_fclose)(FILE *f) = NULL;  static int (*_access)(const char *, int) = NULL; @@ -170,6 +178,38 @@ do { \      pthread_mutex_unlock(&func_mutex); \  } while(0) +#define LOAD_STAT_FUNC() \ +do { \ +    pthread_mutex_lock(&func_mutex); \ +    if (!_stat) \ +        _stat = (int (*)(const char *, struct stat *)) dlsym_fn(RTLD_NEXT, "stat"); \ +    pthread_mutex_unlock(&func_mutex); \ +} while(0) + +#define LOAD_STAT64_FUNC() \ +do { \ +    pthread_mutex_lock(&func_mutex); \ +    if (!_stat64) \ +        _stat64 = (int (*)(const char *, struct stat64 *)) dlsym_fn(RTLD_NEXT, "stat64"); \ +    pthread_mutex_unlock(&func_mutex); \ +} while(0) + +#define LOAD_XSTAT_FUNC() \ +do { \ +    pthread_mutex_lock(&func_mutex); \ +    if (!___xstat) \ +        ___xstat = (int (*)(int, const char *, struct stat *)) dlsym_fn(RTLD_NEXT, "__xstat"); \ +    pthread_mutex_unlock(&func_mutex); \ +} while(0) + +#define LOAD_XSTAT64_FUNC() \ +do { \ +    pthread_mutex_lock(&func_mutex); \ +    if (!___xstat64) \ +        ___xstat64 = (int (*)(int, const char *, struct stat64 *)) dlsym_fn(RTLD_NEXT, "__xstat64"); \ +    pthread_mutex_unlock(&func_mutex); \ +} while(0) +  #define LOAD_FOPEN_FUNC() \  do { \      pthread_mutex_lock(&func_mutex); \ @@ -2348,7 +2388,107 @@ int access(const char *pathname, int mode) {      return 0;  } +int stat(const char *pathname, struct stat *buf) {  #ifdef HAVE_OPEN64 +    struct stat64 parent; +#else +    struct stat parent; +#endif +    int ret; + +    if (!pathname || !buf) { +        errno = EFAULT; +        return -1; +    } + +    if (strcmp(pathname, "/dev/dsp") != 0 && +        strcmp(pathname, "/dev/adsp") != 0 && +        strcmp(pathname, "/dev/sndstat") != 0 && +        strcmp(pathname, "/dev/mixer") != 0) { +        debug(DEBUG_LEVEL_VERBOSE, __FILE__": stat(%s)\n", pathname); +        LOAD_STAT_FUNC(); +        return _stat(pathname, buf); +    } + +    debug(DEBUG_LEVEL_NORMAL, __FILE__": stat(%s)\n", pathname); + +#ifdef _STAT_VER +#ifdef HAVE_OPEN64 +    ret = __xstat64(_STAT_VER, "/dev", &parent); +#else +    ret = __xstat(_STAT_VER, "/dev", &parent); +#endif +#else +#ifdef HAVE_OPEN64 +    ret = stat64("/dev", &parent); +#else +    ret = stat("/dev", &parent); +#endif +#endif + +    if (ret) { +        debug(DEBUG_LEVEL_NORMAL, __FILE__": unable to stat \"/dev\"\n"); +        return -1; +    } + +    buf->st_dev = parent.st_dev; +    buf->st_ino = 0xDEADBEEF;   /* FIXME: Can we do this in a safe way? */ +    buf->st_mode = S_IFCHR | S_IRUSR | S_IWUSR; +    buf->st_nlink = 1; +    buf->st_uid = getuid(); +    buf->st_gid = getgid(); +    buf->st_rdev = 0x0E03;      /* FIXME: Linux specific */ +    buf->st_size = 0; +    buf->st_atime = 1181557705; +    buf->st_mtime = 1181557705; +    buf->st_ctime = 1181557705; +    buf->st_blksize = 1; +    buf->st_blocks = 0; + +    return 0; +} + +#ifdef HAVE_OPEN64 + +int stat64(const char *pathname, struct stat64 *buf) { +    struct stat oldbuf; +    int ret; + +    if (!pathname || !buf) { +        errno = EFAULT; +        return -1; +    } + +    debug(DEBUG_LEVEL_VERBOSE, __FILE__": stat64(%s)\n", pathname); + +    if (strcmp(pathname, "/dev/dsp") != 0 && +        strcmp(pathname, "/dev/adsp") != 0 && +        strcmp(pathname, "/dev/sndstat") != 0 && +        strcmp(pathname, "/dev/mixer") != 0) { +        LOAD_STAT64_FUNC(); +        return _stat64(pathname, buf); +    } + +    ret = stat(pathname, &oldbuf); +    if (ret) +        return ret; + +    buf->st_dev = oldbuf.st_dev; +    buf->st_ino = oldbuf.st_ino; +    buf->st_mode = oldbuf.st_mode; +    buf->st_nlink = oldbuf.st_nlink; +    buf->st_uid = oldbuf.st_uid; +    buf->st_gid = oldbuf.st_gid; +    buf->st_rdev = oldbuf.st_rdev; +    buf->st_size = oldbuf.st_size; +    buf->st_atime = oldbuf.st_atime; +    buf->st_mtime = oldbuf.st_mtime; +    buf->st_ctime = oldbuf.st_ctime; +    buf->st_blksize = oldbuf.st_blksize; +    buf->st_blocks = oldbuf.st_blocks; + +    return 0; +}  int open64(const char *filename, int flags, ...) {      va_list args; @@ -2374,6 +2514,62 @@ int open64(const char *filename, int flags, ...) {  #endif +#ifdef _STAT_VER + +int __xstat(int ver, const char *pathname, struct stat *buf) { +    if (!pathname || !buf) { +        errno = EFAULT; +        return -1; +    } + +    debug(DEBUG_LEVEL_VERBOSE, __FILE__": __xstat(%s)\n", pathname); + +    if (strcmp(pathname, "/dev/dsp") != 0 && +        strcmp(pathname, "/dev/adsp") != 0 && +        strcmp(pathname, "/dev/sndstat") != 0 && +        strcmp(pathname, "/dev/mixer") != 0) { +        LOAD_XSTAT_FUNC(); +        return ___xstat(ver, pathname, buf); +    } + +    if (ver != _STAT_VER) { +        errno = EINVAL; +        return -1; +    } + +    return stat(pathname, buf); +} + +#ifdef HAVE_OPEN64 + +int __xstat64(int ver, const char *pathname, struct stat64 *buf) { +    if (!pathname || !buf) { +        errno = EFAULT; +        return -1; +    } + +    debug(DEBUG_LEVEL_VERBOSE, __FILE__": __xstat64(%s)\n", pathname); + +    if (strcmp(pathname, "/dev/dsp") != 0 && +        strcmp(pathname, "/dev/adsp") != 0 && +        strcmp(pathname, "/dev/sndstat") != 0 && +        strcmp(pathname, "/dev/mixer") != 0) { +        LOAD_XSTAT64_FUNC(); +        return ___xstat64(ver, pathname, buf); +    } + +    if (ver != _STAT_VER) { +        errno = EINVAL; +        return -1; +    } + +    return stat64(pathname, buf); +} + +#endif + +#endif +  FILE* fopen(const char *filename, const char *mode) {      FILE *f = NULL;      int fd;  | 
