Search
lxdream.org :: lxdream/src/drivers/cdrom/sector.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/drivers/cdrom/sector.c
changeset 1107:7b279d10f46f
prev1099:566cdeb157ec
next1108:305ef2082079
author nkeynes
date Mon May 17 22:01:23 2010 +1000 (12 years ago)
permissions -rw-r--r--
last change Rip out my hacked-up isofs code and replace with libisofs. Much better.
file annotate diff log raw
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.3 @@ -25,6 +25,7 @@
1.4 #include <unistd.h>
1.5 #include <fcntl.h>
1.6
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.13 }
1.14
1.15 +/********************** Temporary file implementation ************************/
1.16 +/**
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.21 + */
1.22 +
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.27 +
1.28 +static GList *tmpfile_open_list = NULL;
1.29 +static gboolean tmpfile_atexit_installed = 0; /* TRUE to indicate atexit hook is registered */
1.30 +
1.31 +/**
1.32 + * atexit hook to destroy any open tmpfiles - make sure they're deleted.
1.33 + */
1.34 +static void tmpfile_atexit_hook(void)
1.35 +{
1.36 + GList *ptr;
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.41 + }
1.42 +}
1.43 +
1.44 +
1.45 +static void tmpfile_sector_source_destroy( sector_source_t dev )
1.46 +{
1.47 + assert( IS_SECTOR_SOURCE_TYPE(dev,FILE_SECTOR_SOURCE) );
1.48 + tmpfile_sector_source_t fdev = (tmpfile_sector_source_t)dev;
1.49 +
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.56 +}
1.57 +
1.58 +sector_source_t tmpfile_sector_source_new( sector_mode_t mode )
1.59 +{
1.60 + if( !tmpfile_atexit_installed ) {
1.61 + atexit(tmpfile_atexit_hook);
1.62 + }
1.63 +
1.64 + gchar *tmpdir = getenv("TMPDIR");
1.65 + if( tmpdir == NULL ) {
1.66 + tmpdir = "/tmp";
1.67 + }
1.68 + gchar *tempfile = get_filename_at(tmpdir, "cd.XXXXXXX");
1.69 + int fd = mkstemp( tempfile );
1.70 + if( fd == -1 ) {
1.71 + g_free(tempfile);
1.72 + return FALSE;
1.73 + }
1.74 +
1.75 + FILE *f = fdopen( fd, "w+" );
1.76 + if( f == NULL ) {
1.77 + close(fd);
1.78 + unlink(tempfile);
1.79 + g_free(tempfile);
1.80 + return NULL;
1.81 + }
1.82 +
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.88 +}
1.89 +
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.96 +
1.97 +static void mem_sector_source_destroy( sector_source_t dev )
1.98 +{
1.99 + assert( IS_SECTOR_SOURCE_TYPE(dev,MEM_SECTOR_SOURCE) );
1.100 + mem_sector_source_t mdev = (mem_sector_source_t)dev;
1.101 +
1.102 + if( mdev->freeOnDestroy ) {
1.103 + free(mdev->buffer);
1.104 + }
1.105 + mdev->buffer = NULL;
1.106 + default_sector_source_destroy(dev);
1.107 +}
1.108 +
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.110 +{
1.111 + assert( IS_SECTOR_SOURCE_TYPE(dev,MEM_SECTOR_SOURCE) );
1.112 + mem_sector_source_t mdev = (mem_sector_source_t)dev;
1.113 +
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.118 +
1.119 + memcpy( buf, mdev->buffer + off, size );
1.120 + return CDROM_ERROR_OK;
1.121 +}
1.122 +
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.125 +{
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.132 +}
1.133 +
1.134 +sector_source_t mem_sector_source_new( sector_mode_t mode, cdrom_count_t sector_count )
1.135 +{
1.136 + return mem_sector_source_new_buffer( g_malloc( sector_count * CDROM_SECTOR_SIZE(mode) ), mode,
1.137 + sector_count, TRUE );
1.138 +}
1.139 +
1.140 +unsigned char *mem_sector_source_get_buffer( sector_source_t dev )
1.141 +{
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.145 +}
1.146 +
1.147 +
1.148 /************************ Track device implementation *************************/
1.149 typedef struct track_sector_source {
1.150 struct sector_source dev;
.