[GRASS-dev] simplify G_convert_dirseps_to_host(G_tempfile()) ?

Paul Kelly paul-grass at stjohnspoint.co.uk
Mon Jun 18 05:55:19 EDT 2007


On Mon, 18 Jun 2007, Paul Kelly wrote:

> On Mon, 18 Jun 2007, Hamish wrote:
>
>> [r.average]
>> 
>> should G_tempfile() be calling G_convert_dirseps_to_host() internally,
>> rather than having individual modules calling it? (ie often forgetting
>> to call it)
>
> I don't think so - G_convert_dirseps_to_host() only needs to be called in 
> certain situations, when the generated path will be used directly by external 
> commands on the system. I think to unconditionally call it would confuse its 
> purpose. But then again in the longrun it might be a good idea to generally 
> simplify things as you said. Hmm, I'm not so sure now. But there may be cases 
> which call it and expect to have '/' directory separators there for some 
> further processing; I wouldn't like to just change it without an audit of 
> where it is used. Which modules were you thinking of anyway?
>
> FWIW I've attached my proposed changes to lib/gis/tempfile.c that I still
             ^^^^^^^^
Oops - didn't even upload the diff never mind attach it. But here it is 
now if anyone is interested. Interestingly, the patch forces all generated 
filenames to have '/' directory separators - presumably because I was 
concerned that some modules might expect this, although I can't remember 
to be sure...

> have in my local source tree. They were intended to split the usage of 
> G_tempfile() between modules that are genuinely using it as a tempfile for 
> creating large temporary maps as was originally intended, and those that are 
> just using it as a general small tempfile function. They also make some 
> changes to make it more Windows compatible. But we decided they were too 
> controversial to commit in case they broke things - maybe in some way we can 
> eventually merge them though.
>
> Paul
>
> _______________________________________________
> grass-dev mailing list
> grass-dev at grass.itc.it
> http://grass.itc.it/mailman/listinfo/grass-dev
>
>
-------------- next part --------------
Index: lib/gis/tempfile.c

===================================================================

RCS file: /home/grass/grassrepository/grass6/lib/gis/tempfile.c,v

retrieving revision 2.5

diff -u -r2.5 tempfile.c

--- lib/gis/tempfile.c	14 Apr 2007 23:02:01 -0000	2.5

+++ lib/gis/tempfile.c	18 Jun 2007 09:17:45 -0000

@@ -11,36 +11,62 @@

  * \date 1999-2006

  */

 

+#include <stdio.h>

+#include <stdlib.h>

 #include <string.h>

 #include <unistd.h>

 #include <sys/stat.h>

+#include <sys/types.h>

 #include <grass/gis.h>

 

-

-/**

- * \fn char *G_tempfile (void)

+/*!

+ * \brief returns a temporary file name on the same disk as the current mapset

  *

- * \brief Returns a temporary file name.

+ * This function returns a pointer to a string containing a unique file name 

+ * that can be used as a temporary file within the module. Successive calls 

+ * to the function will generate new names.

+ * 

+ * Only the file name is generated. The file itself is not created. To create the

+ * file, the module must use standard UNIX functions which create and open files,

+ * e.g., creat() or fopen(). The filename is guaranteed to be on the same disk

+ * as the current mapset. This means that "draft" output maps can

+ * be moved (with either link()+remove() or rename()) into their final

+ * location upon closure.

+ * 

+ * The programmer should take reasonable care to remove (unlink) the file 

+ * before the module exits. However, GRASS database management will 

+ * eventually remove all temporary files created by G_tempfile_in_mapset() 

+ * that have been left behind by the modules which created them.

+ *

+ *  \return char:  pointer to a character string containing the name.

+ *   the name is copied to allocated memory and may be

+ *   released by the unix free () routine.

+ */

+

+char *G_tempfile_in_mapset(void)

+{

+    return G__tempfile_in_mapset(getpid());

+}

+

+/*!

+ * \brief returns a temporary file name

  *

- * This routine returns a pointer to a string containing a unique 

- * temporary file name that can be used as a temporary file within the 

- * module. Successive calls to <i>G_tempfile()</i> will generate new 

- * names. Only the file name is generated. The file itself is not 

- * created. To create the file, the module must use standard UNIX 

- * functions which create and open files, e.g., <i>creat()</i> or 

- * <i>fopen()</i>.<br>

- *

- * Successive calls will generate different names the names are of the 

- * form pid.n where pid is the programs process id number and n is a 

- * unique identifier.<br>

- *

- * <b>Note:</b> It is recommended to <i>unlink()</i> (remove) the 

- * temp file on exit/error. Only if GRASS is left with 'exit', the GIS 

- * mapset manangement will clean up the temp directory (ETC/clean_temp).

- *

- * \return pointer to a character string containing the name. The name 

- * is copied to allocated memory and may be released by the unix free() 

- * routine.

+ * This function returns a pointer to a string containing a unique file name 

+ * that can be used as a temporary file within the module. Successive calls 

+ * to the function will generate new names.

+ * 

+ * Only the file name is generated. The file itself is not created. To create the

+ * file, the module must use standard UNIX functions which create and open files,

+ * e.g., creat() or fopen().

+ * 

+ * The programmer should take care to remove (unlink) the file before

+ * the module exits. If a module requires not to immediately delete a 

+ * temporary file and instead have it automatically deleted at the end of

+ * the GRASS session, G_tempfile_in_mapset() should be used instead.

+ *

+ *  \return char:  pointer to a character string containing the name.

+ *   the name is copied to allocated memory and may be

+ *   released by the unix free () routine.

  */

 

 char *G_tempfile(void)

@@ -48,10 +74,7 @@

     return G__tempfile(getpid());

 }

 

-

 /**

- * \fn char *G__tempfile (int pid)

- *

  * \brief Create tempfile from process id.

  *

  * See <i>G_tempfile()</i>.

@@ -62,6 +85,65 @@

 

 char *G__tempfile (int pid)

 {

+    char *env_tmpdir = getenv("TMPDIR");

+    char *env_temp = getenv("TEMP");

+    char *prefix, *path = NULL;

+    char dirsep_char[2];       

+    static int uniq = 0;

+    struct stat st;

+   

+    if (pid <= 0)

+	pid = getpid();

+   

+    if (env_tmpdir != NULL)

+	/* This should be somewhere in user home directory on Unix,

+	 * thus ensuring write permission */

+        prefix = G_store(env_tmpdir);

+    else if (env_temp != NULL)

+	/* This should be somewhere in user profile directory on Windows, 

+	 * thus ensuring write permission */

+        prefix = G_store(env_temp);

+    else

+        /* Usually /tmp on Unix or root of current drive on Windows */

+        prefix = G_store(P_tmpdir);

+

+    /* Often there's no harm in having an extra directory separator character

+     * in the middle of a path but just being careful here. */

+    if (G_is_dirsep( prefix[strlen(prefix)-1] )) {	       

+	dirsep_char[0] = '\0';

+    }	    

+    else {	       

+	dirsep_char[0] = GRASS_DIRSEP;

+	dirsep_char[1] = '\0';

+    }

+	    

+    do {

+        if (path != NULL)

+	    G_free(path);

+        path = G_malloc(strlen(prefix) + 40 );

+        sprintf(path, "%s%sgrass-%d.%d", prefix, dirsep_char, pid, uniq++);

+        /* We use '/'-style dirseps within GRASS */

+        G_convert_dirseps_from_host( path );

+    } while (stat(path, &st) == 0);

+

+    G_free(prefix);

+   

+    return path;

+   

+}

+

+

+/**

+ * \brief Create tempfile in current mapset from process id.

+ *

+ * See <i>G_tempfile_in_mapset()</i>.

+ *

+ * \param[in] pid

+ * \return Pointer to string path

+ */

+

+char *G__tempfile_in_mapset (int pid)

+{

     char path[GPATH_MAX];

     char name[GNAME_MAX];

     char element[100];

@@ -78,13 +160,14 @@

     }

     while (stat(path, &st) == 0) ;

 

+    /* We use '/'-style dirseps within GRASS */

+    G_convert_dirseps_from_host (path);

+   

     return G_store (path);

 }

 

 

 /**

- * \fn int G__temp_element (char *element)

- *

  * \brief Populates <b>element</b> with a path string.

  *

  * \param[in,out] element



More information about the grass-dev mailing list