1.1 --- a/src/drivers/cdrom/sector.c Wed Feb 10 18:16:19 2010 +1000
1.2 +++ b/src/drivers/cdrom/sector.c Mon May 17 22:01:23 2010 +1000
1.7 +#include "lxpaths.h"
1.8 #include "drivers/cdrom/sector.h"
1.9 #include "drivers/cdrom/cdrom.h"
1.10 #include "drivers/cdrom/ecc.h"
1.11 @@ -534,6 +535,139 @@
1.12 fref->closeOnDestroy = closeOnDestroy;
1.15 +/********************** Temporary file implementation ************************/
1.17 + * The tmpfile source behaves exactly like a regular file source, except that
1.18 + * it creates a new temporary file, which is deleted on destruction or program
1.19 + * exit. The file is initially empty, so the user will need to get the fd and
1.20 + * write something to it before use.
1.23 +typedef struct tmpfile_sector_source {
1.24 + struct file_sector_source file;
1.25 + const char *filename;
1.26 +} *tmpfile_sector_source_t;
1.28 +static GList *tmpfile_open_list = NULL;
1.29 +static gboolean tmpfile_atexit_installed = 0; /* TRUE to indicate atexit hook is registered */
1.32 + * atexit hook to destroy any open tmpfiles - make sure they're deleted.
1.34 +static void tmpfile_atexit_hook(void)
1.37 + while( tmpfile_open_list != NULL ) {
1.38 + sector_source_t source = (sector_source_t)tmpfile_open_list->data;
1.39 + source->destroy(source);
1.40 + assert( tmpfile_open_list == NULL || tmpfile_open_list->data != source );
1.45 +static void tmpfile_sector_source_destroy( sector_source_t dev )
1.47 + assert( IS_SECTOR_SOURCE_TYPE(dev,FILE_SECTOR_SOURCE) );
1.48 + tmpfile_sector_source_t fdev = (tmpfile_sector_source_t)dev;
1.50 + fclose( fdev->file.file );
1.51 + fdev->file.file = NULL;
1.52 + unlink(fdev->filename);
1.53 + g_free((char *)fdev->filename);
1.54 + tmpfile_open_list = g_list_remove(tmpfile_open_list, fdev);
1.55 + default_sector_source_destroy(dev);
1.58 +sector_source_t tmpfile_sector_source_new( sector_mode_t mode )
1.60 + if( !tmpfile_atexit_installed ) {
1.61 + atexit(tmpfile_atexit_hook);
1.64 + gchar *tmpdir = getenv("TMPDIR");
1.65 + if( tmpdir == NULL ) {
1.68 + gchar *tempfile = get_filename_at(tmpdir, "cd.XXXXXXX");
1.69 + int fd = mkstemp( tempfile );
1.75 + FILE *f = fdopen( fd, "w+" );
1.83 + tmpfile_sector_source_t dev = g_malloc0(sizeof(struct tmpfile_sector_source));
1.84 + dev->file.file = f;
1.85 + dev->filename = tempfile;
1.86 + sector_source_t source = sector_source_init( &dev->file.dev, FILE_SECTOR_SOURCE, mode, 0, file_sector_source_read, tmpfile_sector_source_destroy );
1.87 + tmpfile_open_list = g_list_append(tmpfile_open_list, source);
1.90 +/************************ Memory device implementation *************************/
1.91 +typedef struct mem_sector_source {
1.92 + struct sector_source dev;
1.93 + unsigned char *buffer;
1.94 + gboolean freeOnDestroy;
1.95 +} *mem_sector_source_t;
1.97 +static void mem_sector_source_destroy( sector_source_t dev )
1.99 + assert( IS_SECTOR_SOURCE_TYPE(dev,MEM_SECTOR_SOURCE) );
1.100 + mem_sector_source_t mdev = (mem_sector_source_t)dev;
1.102 + if( mdev->freeOnDestroy ) {
1.103 + free(mdev->buffer);
1.105 + mdev->buffer = NULL;
1.106 + default_sector_source_destroy(dev);
1.109 +static cdrom_error_t mem_sector_source_read( sector_source_t dev, cdrom_lba_t lba, cdrom_count_t block_count, unsigned char *buf )
1.111 + assert( IS_SECTOR_SOURCE_TYPE(dev,MEM_SECTOR_SOURCE) );
1.112 + mem_sector_source_t mdev = (mem_sector_source_t)dev;
1.114 + if( (lba + block_count) >= dev->size )
1.115 + return CDROM_ERROR_BADREAD;
1.116 + uint32_t off = lba * CDROM_SECTOR_SIZE(dev->mode);
1.117 + uint32_t size = block_count * CDROM_SECTOR_SIZE(dev->mode);
1.119 + memcpy( buf, mdev->buffer + off, size );
1.120 + return CDROM_ERROR_OK;
1.123 +sector_source_t mem_sector_source_new_buffer( unsigned char *buffer, sector_mode_t mode,
1.124 + cdrom_count_t sector_count, gboolean freeOnDestroy )
1.126 + assert( mode != SECTOR_UNKNOWN );
1.127 + assert( buffer != NULL );
1.128 + mem_sector_source_t dev = g_malloc(sizeof(struct mem_sector_source));
1.129 + dev->buffer = buffer;
1.130 + dev->freeOnDestroy = freeOnDestroy;
1.131 + return sector_source_init( &dev->dev, MEM_SECTOR_SOURCE, mode, sector_count, mem_sector_source_read, mem_sector_source_destroy );
1.134 +sector_source_t mem_sector_source_new( sector_mode_t mode, cdrom_count_t sector_count )
1.136 + return mem_sector_source_new_buffer( g_malloc( sector_count * CDROM_SECTOR_SIZE(mode) ), mode,
1.137 + sector_count, TRUE );
1.140 +unsigned char *mem_sector_source_get_buffer( sector_source_t dev )
1.142 + assert( IS_SECTOR_SOURCE_TYPE(dev,MEM_SECTOR_SOURCE) );
1.143 + mem_sector_source_t mdev = (mem_sector_source_t)dev;
1.144 + return mdev->buffer;
1.148 /************************ Track device implementation *************************/
1.149 typedef struct track_sector_source {
1.150 struct sector_source dev;