Re: g_file_write()
- From: Soeren Sandmann <sandmann daimi au dk>
- To: "Alexis S. L. Carvalho" <alexis cecm usp br>
- Cc: tml iki fi, jody gnome org, scott asofyet org, mclasen redhat com, gtk-devel-list gnome org, mortenw gnome org
- Subject: Re: g_file_write()
- Date: 23 Mar 2005 05:38:26 +0100
Soeren Sandmann <sandmann daimi au dk> writes:
> I think this is a serious problem. The file should be created with the
> umask permissions. You can do this:
>
> #ifndef G_OS_WIN32
> {
> mode_t mode = umask (0);
> umask (mode);
>
> chmod (filename, mode);
> }
> #endif
>
> but then there is a race condition with another thread setting
> umask. This can be avoided by doing it in a separate process:
>
> pid = fork();
>
> if (pid == -1)
> {
> report error
> }
> else if (pid == 0)
> {
> /* child */
> umask/chmod ...
> exit (errno);
> }
> else
> {
> /* parent */
> int err;
>
> waitpid(pid, &err, 0);
>
> if (err != 0)
> ....;
> }
>
> Is there a simpler way to do this?
If there is, I don't know it. I have put up a patch to do the chmod()
in a child process:
http://www.daimi.au.dk/~sandmann/umask-fork.patch
In addition I took a look at the stdio output from libgsf. One thing
that may be worth considering adobting is the symlink following code
they have. Currently g_file_replace() will replace the symlink instead
of the linked file, which will probably surprise some people.
This is the function in question:
static char *
follow_symlinks (char const *filename, GError **error)
{
gchar *followed_filename, *link;
gint link_count = 0;
g_return_val_if_fail (filename != NULL, NULL);
followed_filename = g_strdup (filename);
while ((link = g_file_read_link (followed_filename, NULL)) != NULL &&
++link_count <= GSF_MAX_LINK_LEVEL) {
if (g_path_is_absolute (link)) {
g_free (followed_filename);
followed_filename = link;
} else {
/* If the linkname is not an absolute path name, append
* it to the directory name of the followed filename. E.g.
* we may have /foo/bar/baz.lnk -> eek.txt, which really
* is /foo/bar/eek.txt.
*/
gchar *dir = g_path_get_dirname (followed_filename);
g_free (followed_filename);
followed_filename = g_build_filename (dir, link, NULL);
g_free (dir);
g_free (link);
}
}
if (link == NULL)
return followed_filename;
/* Too many symlinks */
if (error != NULL)
*error = g_error_new_literal (gsf_output_error_id (), ELOOP,
g_strerror (ELOOP));
g_free (followed_filename);
return NULL;
}
Maybe we could even add it as g_follow_symlik() to avoid duplication
of code in libgsf.
Søren
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]