Search
lxdream.org :: lxdream/src/loader.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/loader.c
changeset 1109:700c5ab26a63
prev1108:305ef2082079
next1117:0b14a8ec373b
author nkeynes
date Thu Jun 10 22:13:16 2010 +1000 (11 years ago)
permissions -rw-r--r--
last change Integrate executable wrapping into the user interface
- command-line now loads wrapped by default, -e <bin> to run binary
- add support for .bin executables
- Add useful (internal) error codes
file annotate diff log raw
1.1 --- a/src/loader.c Fri Jun 04 09:13:40 2010 +1000
1.2 +++ b/src/loader.c Thu Jun 10 22:13:16 2010 +1000
1.3 @@ -33,6 +33,7 @@
1.4 #include "loader.h"
1.5 #include "drivers/cdrom/cdrom.h"
1.6 #include "drivers/cdrom/isofs.h"
1.7 +#include "gdrom/gdrom.h"
1.8
1.9 const char bootstrap_magic[32] = "SEGA SEGAKATANA SEGA ENTERPRISES";
1.10 const char iso_magic[6] = "\001CD001";
1.11 @@ -41,101 +42,171 @@
1.12 { "bin", "SH4 Bin file" },
1.13 { NULL, NULL } };
1.14
1.15 -gboolean file_load_elf_fd( const gchar *filename, int fd );
1.16 +static cdrom_disc_t cdrom_wrap_elf( cdrom_disc_type_t type, const gchar *filename, int fd, ERROR *err );
1.17 +static cdrom_disc_t cdrom_wrap_binary( cdrom_disc_type_t type, const gchar *filename, int fd, ERROR *err );
1.18 +static gboolean file_load_binary( const gchar *filename, int fd, ERROR *err );
1.19 +static gboolean file_load_elf( const gchar *filename, int fd, ERROR *err );
1.20
1.21 -typedef enum {
1.22 - FILE_ERROR,
1.23 - FILE_BINARY,
1.24 - FILE_ELF,
1.25 - FILE_ISO,
1.26 - FILE_DISC,
1.27 - FILE_ZIP,
1.28 - FILE_SAVE_STATE,
1.29 -} lxdream_file_type_t;
1.30
1.31 -static lxdream_file_type_t file_magic( const gchar *filename, int fd, ERROR *err )
1.32 +
1.33 +lxdream_file_type_t file_identify( const gchar *filename, int fd, ERROR *err )
1.34 {
1.35 char buf[32];
1.36 + lxdream_file_type_t result = FILE_UNKNOWN;
1.37 + gboolean mustClose = FALSE;
1.38 + off_t posn;
1.39
1.40 - /* begin magic */
1.41 - if( read( fd, buf, 32 ) != 32 ) {
1.42 - SET_ERROR( err, errno, "Unable to read from file '%s'", filename );
1.43 - return FILE_ERROR;
1.44 -
1.45 + if( fd == -1 ) {
1.46 + fd = open( filename, O_RDONLY );
1.47 + if( fd == -1 ) {
1.48 + SET_ERROR( err, LX_ERR_FILE_NOOPEN, "Unable to open file '%s' (%s)" ,filename, strerror(errno) );
1.49 + return FILE_ERROR;
1.50 + }
1.51 + mustClose = TRUE;
1.52 + } else {
1.53 + /* Save current file position */
1.54 + posn = lseek(fd, 0, SEEK_CUR);
1.55 + if( posn == -1 ) {
1.56 + SET_ERROR( err, LX_ERR_FILE_IOERROR, "Unable to read from file '%s' (%s)", filename, strerror(errno) );
1.57 + return FILE_ERROR;
1.58 + }
1.59 }
1.60
1.61 - lseek( fd, 0, SEEK_SET );
1.62 - if( buf[0] == 0x7F && buf[1] == 'E' &&
1.63 + int status = read(fd, buf, 32);
1.64 + if( status == -1 ) {
1.65 + SET_ERROR( err, LX_ERR_FILE_IOERROR, "Unable to read from file '%s' (%s)", filename, strerror(errno) );
1.66 + result = FILE_ERROR;
1.67 + } else if( status != 32 ) {
1.68 + result = FILE_UNKNOWN;
1.69 + } else if( buf[0] == 0x7F && buf[1] == 'E' &&
1.70 buf[2] == 'L' && buf[3] == 'F' ) {
1.71 - return FILE_ELF;
1.72 + result = FILE_ELF;
1.73 } else if( memcmp( buf, "PK\x03\x04", 4 ) == 0 ) {
1.74 - return FILE_ZIP;
1.75 + result = FILE_ZIP;
1.76 } else if( memcmp( buf, DREAMCAST_SAVE_MAGIC, 16 ) == 0 ) {
1.77 - return FILE_SAVE_STATE;
1.78 + result = FILE_SAVE_STATE;
1.79 } else if( lseek( fd, 32768, SEEK_SET ) == 32768 &&
1.80 read( fd, buf, 8 ) == 8 &&
1.81 memcmp( buf, iso_magic, 6) == 0 ) {
1.82 - lseek( fd, 0, SEEK_SET );
1.83 - return FILE_ISO;
1.84 + result = FILE_ISO;
1.85 + } else {
1.86 + /* Check the file extension - .bin = sh4 binary */
1.87 + int len = strlen(filename);
1.88 + struct stat st;
1.89 +
1.90 + if( len > 4 && strcasecmp(filename + (len-4), ".bin") == 0 &&
1.91 + fstat(fd, &st) != -1 && st.st_size <= BINARY_MAX_SIZE ) {
1.92 + result = FILE_BINARY;
1.93 + }
1.94 }
1.95 - lseek( fd, 0, SEEK_SET );
1.96 - return FILE_BINARY;
1.97 +
1.98 + if( mustClose ) {
1.99 + close(fd);
1.100 + } else {
1.101 + lseek( fd, posn, SEEK_SET );
1.102 + }
1.103 + return result;
1.104 }
1.105
1.106
1.107 -gboolean file_load_magic( const gchar *filename )
1.108 +gboolean file_load_exec( const gchar *filename, ERROR *err )
1.109 {
1.110 - char buf[32];
1.111 - struct stat st;
1.112 gboolean result = TRUE;
1.113
1.114 int fd = open( filename, O_RDONLY );
1.115 if( fd == -1 ) {
1.116 + SET_ERROR( err, LX_ERR_FILE_NOOPEN, "Unable to open file '%s' (%s)" ,filename, strerror(errno) );
1.117 return FALSE;
1.118 }
1.119
1.120 - fstat( fd, &st );
1.121 + lxdream_file_type_t type = file_identify(filename, fd, err);
1.122 + switch( type ) {
1.123 + case FILE_ERROR:
1.124 + result = FALSE;
1.125 + break;
1.126 + case FILE_ELF:
1.127 + result = file_load_elf( filename, fd, err );
1.128 + break;
1.129 + case FILE_BINARY:
1.130 + result = file_load_binary( filename, fd, err );
1.131 + break;
1.132 + default:
1.133 + SET_ERROR( err, LX_ERR_FILE_UNKNOWN, "File '%s' could not be recognized as an executable binary", filename );
1.134 + result = FALSE;
1.135 + break;
1.136 + }
1.137
1.138 - /* begin magic */
1.139 - if( read( fd, buf, 32 ) != 32 ) {
1.140 - ERROR( "Unable to read from file '%s'", filename );
1.141 - close(fd);
1.142 - return FALSE;
1.143 + close(fd);
1.144 + return result;
1.145 +}
1.146 +
1.147 +lxdream_file_type_t file_load_magic( const gchar *filename, gboolean wrap_exec, ERROR *err )
1.148 +{
1.149 + gboolean result;
1.150 + /* Try disc types first */
1.151 + cdrom_disc_t disc = cdrom_disc_open( filename, err );
1.152 + if( disc != NULL ) {
1.153 + gdrom_mount_disc(disc);
1.154 + return FILE_DISC;
1.155 + } else if( err != LX_ERR_FILE_UNKNOWN ) {
1.156 + return FILE_ERROR;
1.157 }
1.158 - if( memcmp( buf, bootstrap_magic, 32 ) == 0 ) {
1.159 - /* we have a DC bootstrap */
1.160 - if( st.st_size == BOOTSTRAP_SIZE ) {
1.161 - sh4ptr_t load = mem_get_region( BOOTSTRAP_LOAD_ADDR );
1.162 - lseek( fd, 0, SEEK_SET );
1.163 - read( fd, load, BOOTSTRAP_SIZE );
1.164 - bootstrap_dump( load, TRUE );
1.165 - dreamcast_program_loaded( filename, BOOTSTRAP_LOAD_ADDR + 0x300 );
1.166 +
1.167 + int fd = open( filename, O_RDONLY );
1.168 + if( fd == -1 ) {
1.169 + SET_ERROR( err, LX_ERR_FILE_NOOPEN, "Unable to open file '%s' (%s)" ,filename, strerror(errno) );
1.170 + return FILE_ERROR;
1.171 + }
1.172 +
1.173 + lxdream_file_type_t type = file_identify(filename, fd, err);
1.174 + switch( type ) {
1.175 + case FILE_ERROR:
1.176 + result = FALSE;
1.177 + break;
1.178 + case FILE_ELF:
1.179 + if( wrap_exec ) {
1.180 + disc = cdrom_wrap_elf( CDROM_DISC_XA, filename, fd, err );
1.181 + result = disc != NULL;
1.182 + if( disc != NULL ) {
1.183 + gdrom_mount_disc(disc);
1.184 + }
1.185 } else {
1.186 - /* look for a valid ISO9660 header */
1.187 - lseek( fd, 32768, SEEK_SET );
1.188 - read( fd, buf, 8 );
1.189 - if( memcmp( buf, iso_magic, 6 ) == 0 ) {
1.190 - /* Alright, got it */
1.191 - WARN( "ISO images not supported yet" );
1.192 + result = file_load_elf( filename, fd, err );
1.193 + }
1.194 + break;
1.195 + case FILE_BINARY:
1.196 + if( wrap_exec ) {
1.197 + disc = cdrom_wrap_binary( CDROM_DISC_XA, filename, fd, err );
1.198 + result = disc != NULL;
1.199 + if( disc != NULL ) {
1.200 + gdrom_mount_disc(disc);
1.201 }
1.202 + } else {
1.203 + result = file_load_binary( filename, fd, err );
1.204 }
1.205 - } else if( memcmp( buf, "PK\x03\x04", 4 ) == 0 ) {
1.206 - /* ZIP file, aka SBI file */
1.207 - WARN( "SBI files not supported yet" );
1.208 + break;
1.209 + case FILE_SAVE_STATE:
1.210 + result = dreamcast_load_state( filename );
1.211 + break;
1.212 + case FILE_ZIP:
1.213 + SET_ERROR( err, LX_ERR_FILE_UNSUP, "ZIP/SBI not currently supported" );
1.214 result = FALSE;
1.215 - } else if( memcmp( buf, DREAMCAST_SAVE_MAGIC, 16 ) == 0 ) {
1.216 - /* Save state */
1.217 - result = (dreamcast_load_state( filename )==0);
1.218 - } else if( buf[0] == 0x7F && buf[1] == 'E' &&
1.219 - buf[2] == 'L' && buf[3] == 'F' ) {
1.220 - /* ELF binary */
1.221 - lseek( fd, 0, SEEK_SET );
1.222 - result = file_load_elf_fd( filename, fd );
1.223 - } else {
1.224 + break;
1.225 + case FILE_ISO:
1.226 + SET_ERROR( err, LX_ERR_FILE_UNSUP, "ISO files are not currently supported" );
1.227 result = FALSE;
1.228 + break;
1.229 + default:
1.230 + SET_ERROR( err, LX_ERR_FILE_UNKNOWN, "File '%s' could not be recognized", filename );
1.231 + result = FALSE;
1.232 + break;
1.233 }
1.234 close(fd);
1.235 - return result;
1.236 + if( result ) {
1.237 + CLEAR_ERROR(err);
1.238 + return type;
1.239 + }
1.240 + return FILE_ERROR;
1.241 }
1.242
1.243 void file_load_postload( const gchar *filename, int pc )
1.244 @@ -156,18 +227,7 @@
1.245 }
1.246
1.247
1.248 -gboolean file_load_binary( const gchar *filename )
1.249 -{
1.250 - /* Load the binary itself */
1.251 - if( mem_load_block( filename, BINARY_LOAD_ADDR, -1 ) == 0 ) {
1.252 - file_load_postload( filename, BINARY_LOAD_ADDR );
1.253 - return TRUE;
1.254 - } else {
1.255 - return FALSE;
1.256 - }
1.257 -}
1.258 -
1.259 -gboolean is_sh4_elf( Elf32_Ehdr *head )
1.260 +static gboolean is_sh4_elf( Elf32_Ehdr *head )
1.261 {
1.262 return ( head->e_ident[EI_CLASS] == ELFCLASS32 &&
1.263 head->e_ident[EI_DATA] == ELFDATA2LSB &&
1.264 @@ -177,7 +237,7 @@
1.265 head->e_version == 1 );
1.266 }
1.267
1.268 -gboolean is_arm_elf( Elf32_Ehdr *head )
1.269 +static gboolean is_arm_elf( Elf32_Ehdr *head )
1.270 {
1.271 return ( head->e_ident[EI_CLASS] == ELFCLASS32 &&
1.272 head->e_ident[EI_DATA] == ELFDATA2LSB &&
1.273 @@ -187,7 +247,7 @@
1.274 head->e_version == 1 );
1.275 }
1.276
1.277 -gboolean file_load_elf_fd( const gchar *filename, int fd )
1.278 +static gboolean file_load_elf( const gchar *filename, int fd, ERROR *err )
1.279 {
1.280 Elf32_Ehdr head;
1.281 Elf32_Phdr phdr;
1.282 @@ -196,7 +256,7 @@
1.283 if( read( fd, &head, sizeof(head) ) != sizeof(head) )
1.284 return FALSE;
1.285 if( !is_sh4_elf(&head) ) {
1.286 - ERROR( "File is not an SH4 ELF executable file" );
1.287 + SET_ERROR( err, LX_ERR_FILE_INVALID, "File is not an SH4 ELF executable file" );
1.288 return FALSE;
1.289 }
1.290
1.291 @@ -211,7 +271,6 @@
1.292 if( phdr.p_memsz > phdr.p_filesz ) {
1.293 memset( target + phdr.p_filesz, 0, phdr.p_memsz - phdr.p_filesz );
1.294 }
1.295 - INFO( "Loaded %d bytes to %08X", phdr.p_filesz, phdr.p_vaddr );
1.296 }
1.297 }
1.298
1.299 @@ -219,6 +278,30 @@
1.300 return TRUE;
1.301 }
1.302
1.303 +static gboolean file_load_binary( const gchar *filename, int fd, ERROR *err )
1.304 +{
1.305 + struct stat st;
1.306 +
1.307 + if( fstat( fd, &st ) == -1 ) {
1.308 + SET_ERROR( err, LX_ERR_FILE_IOERROR, "Error reading binary file '%s' (%s)", filename, strerror(errno) );
1.309 + return FALSE;
1.310 + }
1.311 +
1.312 + if( st.st_size > BINARY_MAX_SIZE ) {
1.313 + SET_ERROR( err, LX_ERR_FILE_INVALID, "Binary file '%s' is too large to fit in memory", filename );
1.314 + return FALSE;
1.315 + }
1.316 +
1.317 + sh4ptr_t target = mem_get_region( BINARY_LOAD_ADDR );
1.318 + if( read( fd, target, st.st_size ) != st.st_size ) {
1.319 + SET_ERROR( err, LX_ERR_FILE_IOERROR, "Error reading binary file '%s' (%s)", filename, strerror(errno) );
1.320 + return FALSE;
1.321 + }
1.322 +
1.323 + file_load_postload( filename, BINARY_LOAD_ADDR );
1.324 + return TRUE;
1.325 +}
1.326 +
1.327 /**
1.328 * Create a new CDROM disc containing a single 1ST_READ.BIN.
1.329 * @param type The disc type - must be CDROM_DISC_GDROM or CDROM_DISC_XA
1.330 @@ -233,25 +316,25 @@
1.331 cdrom_lba_t start_lba = 45000; /* GDROM_START */
1.332 char bootstrap[32768];
1.333
1.334 - /* 1. Load in the bootstrap */
1.335 + /* 1. Load in the bootstrap: Note failures here are considered configuration errors */
1.336 gchar *bootstrap_file = lxdream_get_global_config_path_value(CONFIG_BOOTSTRAP);
1.337 if( bootstrap_file == NULL || bootstrap_file[0] == '\0' ) {
1.338 g_free(data);
1.339 - SET_ERROR( err, ENOENT, "Unable to create CD image: bootstrap file is not configured" );
1.340 + SET_ERROR( err, LX_ERR_CONFIG, "Unable to create CD image: bootstrap file is not configured" );
1.341 return NULL;
1.342 }
1.343
1.344 FILE *f = fopen( bootstrap_file, "ro" );
1.345 if( f == NULL ) {
1.346 g_free(data);
1.347 - SET_ERROR( err, errno, "Unable to create CD image: bootstrap file '%s' could not be opened", bootstrap_file );
1.348 + SET_ERROR( err, LX_ERR_CONFIG, "Unable to create CD image: bootstrap file '%s' could not be opened", bootstrap_file );
1.349 return FALSE;
1.350 }
1.351 size_t len = fread( bootstrap, 1, 32768, f );
1.352 fclose(f);
1.353 if( len != 32768 ) {
1.354 g_free(data);
1.355 - SET_ERROR( err, EINVAL, "Unable to create CD image: bootstrap file '%s' is invalid", bootstrap_file );
1.356 + SET_ERROR( err, LX_ERR_CONFIG, "Unable to create CD image: bootstrap file '%s' is invalid", bootstrap_file );
1.357 return FALSE;
1.358 }
1.359
1.360 @@ -280,6 +363,7 @@
1.361 int status = iso_image_new("autocd", &iso);
1.362 if( status != 1 ) {
1.363 g_free(data);
1.364 + SET_ERROR( err, LX_ERR_NOMEM, "Unable to create CD image: out of memory" );
1.365 return NULL;
1.366 }
1.367
1.368 @@ -287,6 +371,7 @@
1.369 if( iso_memory_stream_new(data, bin_size, &stream) != 1 ) {
1.370 g_free(data);
1.371 iso_image_unref(iso);
1.372 + SET_ERROR( err, LX_ERR_NOMEM, "Unable to create CD image: out of memory" );
1.373 return NULL;
1.374 }
1.375 iso_tree_add_new_file(iso_image_get_root(iso), "1ST_READ.BIN", stream, NULL);
1.376 @@ -297,15 +382,15 @@
1.377 return NULL;
1.378 }
1.379
1.380 - cdrom_disc_t disc = cdrom_disc_new_from_track( type, track, start_lba );
1.381 + cdrom_disc_t disc = cdrom_disc_new_from_track( type, track, start_lba, err );
1.382 iso_image_unref(iso);
1.383 if( disc != NULL ) {
1.384 disc->name = g_strdup(filename);
1.385 - }
1.386 + }
1.387 return disc;
1.388 }
1.389
1.390 -cdrom_disc_t cdrom_wrap_elf_fd( cdrom_disc_type_t type, const gchar *filename, int fd, ERROR *err )
1.391 +static cdrom_disc_t cdrom_wrap_elf( cdrom_disc_type_t type, const gchar *filename, int fd, ERROR *err )
1.392 {
1.393 Elf32_Ehdr head;
1.394 int i;
1.395 @@ -313,12 +398,13 @@
1.396 /* Check the file header is actually an SH4 binary */
1.397 if( read( fd, &head, sizeof(head) ) != sizeof(head) )
1.398 return FALSE;
1.399 +
1.400 if( !is_sh4_elf(&head) ) {
1.401 - SET_ERROR( err, EINVAL, "File is not an SH4 ELF executable file" );
1.402 + SET_ERROR( err, LX_ERR_FILE_INVALID, "File is not an SH4 ELF executable file" );
1.403 return FALSE;
1.404 }
1.405 if( head.e_entry != BINARY_LOAD_ADDR ) {
1.406 - SET_ERROR( err, EINVAL, "SH4 Binary has incorrect entry point (should be %08X but is %08X)", BINARY_LOAD_ADDR, head.e_entry );
1.407 + SET_ERROR( err, LX_ERR_FILE_INVALID, "SH4 Binary has incorrect entry point (should be %08X but is %08X)", BINARY_LOAD_ADDR, head.e_entry );
1.408 return FALSE;
1.409 }
1.410
1.411 @@ -326,7 +412,7 @@
1.412 Elf32_Phdr phdr[head.e_phnum];
1.413 lseek( fd, head.e_phoff, SEEK_SET );
1.414 if( read( fd, phdr, sizeof(phdr) ) != sizeof(phdr) ) {
1.415 - SET_ERROR( err, EINVAL, "File is not a valid executable file" );
1.416 + SET_ERROR( err, LX_ERR_FILE_INVALID, "File is not a valid executable file" );
1.417 return FALSE;
1.418 }
1.419
1.420 @@ -342,11 +428,11 @@
1.421 }
1.422
1.423 if( start != BINARY_LOAD_ADDR ) {
1.424 - SET_ERROR( err, EINVAL, "SH4 Binary has incorrect load address (should be %08X but is %08X)", BINARY_LOAD_ADDR, start );
1.425 + SET_ERROR( err, LX_ERR_FILE_INVALID, "SH4 Binary has incorrect load address (should be %08X but is %08X)", BINARY_LOAD_ADDR, start );
1.426 return FALSE;
1.427 }
1.428 if( end >= 0x8D000000 ) {
1.429 - SET_ERROR( err, EINVAL, "SH4 binary is too large to fit in memory (end address is %08X)", end );
1.430 + SET_ERROR( err, LX_ERR_FILE_INVALID, "SH4 binary is too large to fit in memory (end address is %08X)", end );
1.431 return FALSE;
1.432 }
1.433
1.434 @@ -356,7 +442,12 @@
1.435 if( phdr[i].p_type == PT_LOAD ) {
1.436 lseek( fd, phdr[i].p_offset, SEEK_SET );
1.437 uint32_t size = MIN( phdr[i].p_filesz, phdr[i].p_memsz);
1.438 - read( fd, program + phdr[i].p_vaddr, size );
1.439 + int status = read( fd, program + phdr[i].p_vaddr, size );
1.440 + if( status == -1 ) {
1.441 + SET_ERROR( err, LX_ERR_FILE_IOERROR, "I/O error reading SH4 binary %s (%s)", filename, strerror(errno) );
1.442 + } else if( status != size ) {
1.443 + SET_ERROR( err, LX_ERR_FILE_IOERROR, "SH4 binary %s is corrupt", filename );
1.444 + }
1.445 }
1.446 }
1.447
1.448 @@ -364,39 +455,52 @@
1.449 return cdrom_disc_new_wrapped_binary(type, filename, program, end-start, err );
1.450 }
1.451
1.452 -cdrom_disc_t cdrom_wrap_magic( cdrom_disc_type_t type, const gchar *filename, ERROR *err )
1.453 +static cdrom_disc_t cdrom_wrap_binary( cdrom_disc_type_t type, const gchar *filename, int fd, ERROR *err )
1.454 {
1.455 - cdrom_disc_t disc;
1.456 + struct stat st;
1.457 char *data;
1.458 - int len;
1.459 - struct stat st;
1.460 - int fd = open( filename, O_RDONLY );
1.461 - if( fd == -1 ) {
1.462 - SET_ERROR( err, errno, "Unable to open file '%s'", filename );
1.463 + size_t len;
1.464 +
1.465 + if( fstat(fd, &st) == -1 ) {
1.466 + SET_ERROR( err, LX_ERR_FILE_IOERROR, "Error reading binary file '%s' (%s)", filename, strerror(errno) );
1.467 return NULL;
1.468 }
1.469
1.470 -
1.471 - lxdream_file_type_t filetype = file_magic( filename, fd, err );
1.472 - switch( filetype ) {
1.473 - case FILE_BINARY:
1.474 - fstat( fd, &st );
1.475 - data = g_malloc(st.st_size);
1.476 - len = read( fd, data, st.st_size );
1.477 - close(fd);
1.478 - if( len != st.st_size ) {
1.479 - SET_ERROR( err, errno, "Error reading binary file '%s'", filename );
1.480 - return NULL;
1.481 - }
1.482 - return cdrom_disc_new_wrapped_binary( type, filename, data, st.st_size, err );
1.483 - case FILE_ELF:
1.484 - disc = cdrom_wrap_elf_fd(type, filename, fd, err);
1.485 - close(fd);
1.486 - return disc;
1.487 - default:
1.488 - close(fd);
1.489 - SET_ERROR( err, EINVAL, "File '%s' cannot be wrapped (not a binary)", filename );
1.490 + data = g_malloc(st.st_size);
1.491 + len = read( fd, data, st.st_size );
1.492 + if( len != st.st_size ) {
1.493 + SET_ERROR( err, LX_ERR_FILE_IOERROR, "Error reading binary file '%s' (%s)", filename, strerror(errno) );
1.494 + free(data);
1.495 return NULL;
1.496 }
1.497
1.498 + return cdrom_disc_new_wrapped_binary( type, filename, data, st.st_size, err );
1.499 }
1.500 +
1.501 +cdrom_disc_t cdrom_wrap_magic( cdrom_disc_type_t type, const gchar *filename, ERROR *err )
1.502 +{
1.503 + cdrom_disc_t disc = NULL;
1.504 +
1.505 + int fd = open( filename, O_RDONLY );
1.506 + if( fd == -1 ) {
1.507 + SET_ERROR( err, LX_ERR_FILE_NOOPEN, "Unable to open file '%s'", filename );
1.508 + return NULL;
1.509 + }
1.510 +
1.511 + lxdream_file_type_t filetype = file_identify( filename, fd, err );
1.512 + switch( filetype ) {
1.513 + case FILE_ELF:
1.514 + disc = cdrom_wrap_elf(type, filename, fd, err);
1.515 + break;
1.516 + case FILE_BINARY:
1.517 + disc = cdrom_wrap_binary(type, filename, fd, err);
1.518 + break;
1.519 + default:
1.520 + SET_ERROR( err, LX_ERR_FILE_UNKNOWN, "File '%s' cannot be wrapped (not a recognized binary)", filename );
1.521 + break;
1.522 + }
1.523 +
1.524 + close(fd);
1.525 + return disc;
1.526 +
1.527 +}
.