mirror of
https://github.com/n64dev/cen64.git
synced 2025-04-02 10:31:54 -04:00
97 lines
2.1 KiB
C
97 lines
2.1 KiB
C
//
|
|
// os/unix/save_file.c
|
|
//
|
|
// Functions for mapping save files into the address space.
|
|
//
|
|
// This file is subject to the terms and conditions defined in
|
|
// 'LICENSE', which is part of this source code package.
|
|
//
|
|
|
|
#include "save_file.h"
|
|
#include <fcntl.h>
|
|
#include <stddef.h>
|
|
#include <sys/mman.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
|
|
// Unmaps a save file from the host address space.
|
|
int close_save_file(const struct save_file *file) {
|
|
munmap(file->ptr, file->size);
|
|
close(file->fd);
|
|
return 0;
|
|
}
|
|
|
|
// Maps a save into the host address space, returns a pointer.
|
|
int open_save_file(const char *path, size_t size, struct save_file *file, int *created) {
|
|
struct stat sb;
|
|
void *ptr;
|
|
int fd;
|
|
int my_created;
|
|
|
|
// Open the file O_EXCL to see if it exists
|
|
if ((fd = open(path, O_RDWR | O_CREAT | O_EXCL, 0666)) >= 0)
|
|
my_created = 1;
|
|
|
|
// Otherwise just open to the file
|
|
else {
|
|
if ((fd = open(path, O_RDWR)) == -1)
|
|
return -1;
|
|
my_created = 0;
|
|
}
|
|
|
|
if (created != NULL)
|
|
*created = my_created;
|
|
|
|
// Get the file's size, map it into the address space.
|
|
if (fstat(fd, &sb) == -1) {
|
|
close(fd);
|
|
return -1;
|
|
}
|
|
|
|
if ((size_t)sb.st_size != size)
|
|
if (ftruncate(fd, size) == -1) {
|
|
close(fd);
|
|
return -1;
|
|
}
|
|
|
|
if ((ptr = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) {
|
|
close(fd);
|
|
return -1;
|
|
}
|
|
|
|
file->ptr = ptr;
|
|
file->size = size;
|
|
file->fd = fd;
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Opening a game boy save: don't set a specific size and don't create
|
|
// the file if it doesn't exist
|
|
int open_gb_save(const char *path, struct save_file *file) {
|
|
struct stat sb;
|
|
void *ptr;
|
|
int fd;
|
|
|
|
// try to open the file
|
|
if ((fd = open(path, O_RDWR)) == -1)
|
|
return -1;
|
|
|
|
// Get the file's size, map it into the address space.
|
|
if (fstat(fd, &sb) == -1) {
|
|
close(fd);
|
|
return -1;
|
|
}
|
|
|
|
if ((ptr = mmap(NULL, sb.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) {
|
|
close(fd);
|
|
return -1;
|
|
}
|
|
|
|
file->ptr = ptr;
|
|
file->size = sb.st_size;
|
|
file->fd = fd;
|
|
|
|
return 0;
|
|
}
|