str->file_mode = fmode;
str->type = STREAM_TYPE_MEMORY;
str->mark = 0;
+ str->endmark = 0;
str->unicode = FALSE;
if(buf && buflen)
str->file_mode = fmode;
str->type = STREAM_TYPE_MEMORY;
str->mark = 0;
+ str->endmark = 0;
str->unicode = TRUE;
if(buf && buflen)
{
VALID_FILEREF(fileref, return NULL);
- gchar *modestr;
+ const gchar *modestr;
/* Binary mode is 0x000, text mode 0x100 */
gboolean binary = !(fileref->usage & fileusage_TextMode);
switch(fmode)
ILLEGAL_PARAM("Tried to open a nonexistent file, '%s', in read mode", fileref->filename);
return NULL;
}
- modestr = g_strdup(binary? "rb" : "r");
+ modestr = binary? "rb" : "r";
break;
case filemode_Write:
- modestr = g_strdup(binary? "wb" : "w");
+ modestr = binary? "wb" : "w";
break;
case filemode_WriteAppend:
- modestr = g_strdup(binary? "ab" : "a");
- break;
case filemode_ReadWrite:
- if( g_file_test(fileref->filename, G_FILE_TEST_EXISTS) ) {
- modestr = g_strdup(binary? "r+b" : "r+");
- } else {
- modestr = g_strdup(binary? "w+b" : "w+");
+ {
+ /* We have to open the file first and then close it, in order to
+ both make sure it exists and be able to seek in it later */
+ FILE *fp = g_fopen(fileref->filename, binary? "ab" : "a");
+ if(fclose(fp) != 0) {
+ IO_WARNING( "Error opening file", fileref->filename, g_strerror(errno) );
+ return NULL;
}
+ modestr = binary? "r+b" : "r+";
+ }
break;
default:
ILLEGAL_PARAM("Invalid file mode: %u", fmode);
}
FILE *fp = g_fopen(fileref->filename, modestr);
- g_free(modestr);
if(fp == NULL) {
IO_WARNING( "Error opening file", fileref->filename, g_strerror(errno) );
return NULL;
}
+ /* Fast-forward to the end if we are appending */
+ if(fmode == filemode_WriteAppend && fseek(fp, 0, SEEK_END) != 0) {
+ IO_WARNING("Error fast-forwarding file to end", fileref->filename, g_strerror(errno));
+ return NULL;
+ }
+
/* If they opened a file in write mode but didn't specifically get
permission to do so, complain if the file already exists */
if(fileref->orig_filemode == filemode_Read && fmode != filemode_Read) {