Index: stand/common/devopen.c =================================================================== --- stand/common/devopen.c +++ stand/common/devopen.c @@ -28,6 +28,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include "bootstrap.h" @@ -37,14 +38,37 @@ #endif int -devopen(struct open_file *f, const char *fname, const char **file) +devopen(struct open_file *f, const char *fname, const char **file, + struct devdesc *odev) { struct devdesc *dev; int result; - result = archsw.arch_getdev((void **)&dev, fname, file); - if (result) - return (result); + dev = NULL; + if (odev == NULL || (*fname != '/' && strchr(fname, ':') != NULL)) { + /* + * If we weren't passed a device to open on, or if we were + * passed a filename that looks like it could have another + * device specified, then we'll extract that. + */ + result = archsw.arch_getdev((void **)&dev, fname, file); + if (result) + return (result); + } + + if (dev == NULL) { + /* + * We must have had an open device passed to us and the above + * arch_getdev() didn't happen. Each file is assumed to have a + * distinct f_devdata that it's OK to free, so grab a copy. + */ + assert(odev != NULL); + dev = malloc(odev->d_size); + if (dev == NULL) + return (ENOMEM); + memcpy(dev, odev, odev->d_size); + *file = fname; + } /* point to device-specific data so that device open can use it */ f->f_dev = dev->d_dev; Index: stand/libsa/gzipfs.c =================================================================== --- stand/libsa/gzipfs.c +++ stand/libsa/gzipfs.c @@ -181,7 +181,7 @@ sprintf(zfname, "%s.gz", fname); /* Try to open the compressed datafile */ - rawfd = open(zfname, O_RDONLY); + rawfd = open_ondev(zfname, O_RDONLY, (struct devdesc *)f->f_devdata); free(zfname); if (rawfd == -1) return(ENOENT); Index: stand/libsa/open.c =================================================================== --- stand/libsa/open.c +++ stand/libsa/open.c @@ -138,7 +138,7 @@ } int -open(const char *fname, int mode) +open_ondev(const char *fname, int mode, struct devdesc *dev) { struct fs_ops *fs; struct open_file *f; @@ -167,7 +167,7 @@ goto err; } - error = devopen(f, fname, &file); + error = devopen(f, fname, &file, dev); if (error || (((f->f_flags & F_NODEV) == 0) && f->f_dev == NULL)) goto err; @@ -209,3 +209,10 @@ TSEXIT(); return (fd); } + +int +open(const char *fname, int mode) +{ + + return (open_ondev(fname, mode, NULL)); +} Index: stand/libsa/stand.h =================================================================== --- stand/libsa/stand.h +++ stand/libsa/stand.h @@ -291,6 +291,7 @@ extern int mount(const char *dev, const char *path, int flags, void *data); extern int unmount(const char *dev, int flags); +extern int open_ondev(const char *, int, struct devdesc *); extern int open(const char *, int); #define O_RDONLY 0x0 #define O_WRONLY 0x1 @@ -412,7 +413,8 @@ extern int getchar(void); extern int ischar(void); extern void putchar(int); -extern int devopen(struct open_file *, const char *, const char **); +extern int devopen(struct open_file *, const char *, const char **, + struct devdesc *); extern int devclose(struct open_file *f); extern void panic(const char *, ...) __dead2 __printflike(1, 2); extern void panic_action(void) __weak_symbol __dead2;