Artimage
asked on
fopen in unix.
I have a subroutine that opens a file, then calls another routine to do some work on the file, and finally closes the file. The first time I call this routine it works fine, but subsequent calls fail with errno saying "Not a directory".
It is trying to open the same file, and it should truncate if it exists.
So why does the second fopen fail, and how can I get it to work. I don't want to leave the file open between subsequent calls. TIA
The code snippet is here.
void
on_Save_clicked (GtkButton *button,
gpointer mainWindow)
{
GtkCTree * ctree;
char * path;
FILE * fp;
/* Get HOME from environment. */
path = getenv("HOME");
sprintf(path, "%s/.todorc", path);
/* Open the rc file */
if ( (fp = fopen(path,"w")) == NULL) {
perror("Failed to open .todorc for save");
}
else {
ctree = GTK_CTREE (lookup_widget (mainWindow, "Ctree"));
/* Walk the tree in prefix order. Apply the function to each node, starting
at the root.
BUGBUG change stderr to the file we want to save to.
*/
gtk_ctree_pre_recursive (ctree, NULL, Save_Node, (gpointer) fp);
fclose(fp);
}
}
It is trying to open the same file, and it should truncate if it exists.
So why does the second fopen fail, and how can I get it to work. I don't want to leave the file open between subsequent calls. TIA
The code snippet is here.
void
on_Save_clicked (GtkButton *button,
gpointer mainWindow)
{
GtkCTree * ctree;
char * path;
FILE * fp;
/* Get HOME from environment. */
path = getenv("HOME");
sprintf(path, "%s/.todorc", path);
/* Open the rc file */
if ( (fp = fopen(path,"w")) == NULL) {
perror("Failed to open .todorc for save");
}
else {
ctree = GTK_CTREE (lookup_widget (mainWindow, "Ctree"));
/* Walk the tree in prefix order. Apply the function to each node, starting
at the root.
BUGBUG change stderr to the file we want to save to.
*/
gtk_ctree_pre_recursive (ctree, NULL, Save_Node, (gpointer) fp);
fclose(fp);
}
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Hate to correct myself again ;-)
>> 'path' is an unitialied pointer
The memory 'path' points to in your code is 'owned' by the runtime library, so you mustn't write to it.
Another thing
path = malloc ( (strlen ( home) + strlen ("/.todorc") * sizeof ( char));
should read
path = malloc ( (strlen ( home) + strlen ("/.todorc") + 1) * sizeof ( char));
(missing bracket and space for the trailing zero <blushing>)
>> 'path' is an unitialied pointer
The memory 'path' points to in your code is 'owned' by the runtime library, so you mustn't write to it.
Another thing
path = malloc ( (strlen ( home) + strlen ("/.todorc") * sizeof ( char));
should read
path = malloc ( (strlen ( home) + strlen ("/.todorc") + 1) * sizeof ( char));
(missing bracket and space for the trailing zero <blushing>)
ASKER
Just so if anyone else looks this up:
Actually, path points to memory that is "owned" by my environment. But you are correct that I shouldn't be writing to it. The failure comes becuase the subsequent call to getenv was getting the value stored by the last sprintf. Thanks for the help.
Actually, path points to memory that is "owned" by my environment. But you are correct that I shouldn't be writing to it. The failure comes becuase the subsequent call to getenv was getting the value stored by the last sprintf. Thanks for the help.
GtkCTree * ctree;
char* home;
char * path;
FILE * fp;
/* Get HOME from environment. */
home = getenv("HOME");
path = malloc ( (strlen ( home) + strlen ("/.todorc") * sizeof ( char));
sprintf(path, "%s/.todorc", home);
/* Open the rc file */
if ( (fp = fopen(path,"w")) == NULL) {
perror("Failed to open .todorc for save");
}
/* ... */
free (path);
/* ... */