Opened 9 years ago

Closed 8 years ago

Last modified 8 years ago

#1158 closed defect (fixed)

Removing vector map in Windows fails with "Unable to delete vector map"

Reported by: Luigi Ponti Owned by: grass-dev@…
Priority: blocker Milestone: 6.4.2
Component: Vector Version: 6.4.0
Keywords: wingrass, g.mremove, wildcards, v.in.ogr, v.select, g.remove Cc:
CPU: Unspecified Platform: MSWindows 7

Description

wxgui g.mremove called on vector with * wildcard does not work:

(Tue Sep 14 15:24:09 2010)                                                     
g.mremove -f vect=map*                                                         
Removing vector <mapBloomday_Olive_11set10_Avg>
Unable to delete file 'C:\cygwin\home\andy/latlong/luigi/vector/mapBloomday_Olive_11set10_Avg/hist'
couldn't be removed
<mapBloomday_Olive_11set10_Avg> nothing removed
(Tue Sep 14 15:24:10 2010) Command finished (0 sec)

wxgui g.mremove called with full vector name works fine:

(Tue Sep 14 15:27:01 2010)                                                     
g.mremove -f vect=mapBloomday_Olive_11set10_Avg                                
Removing vector <mapBloomday_Olive_11set10_Avg>
(Tue Sep 14 15:27:01 2010) Command finished (0 sec)       

There was only that vector map starting with map* in current location.

Deleting rasters with g.mremove works fine both ways.

Trying same test with an old (May 29) WinGRASS-6.4.svn installed on the same machine;

Wildcards work:

(Tue Sep 14 15:49:46 2010)                                                     
g.mremove -f vect=map*                                                         
Removing vector <mapBloomday_Olive_11set10_Avg>
(Tue Sep 14 15:49:47 2010) Command finished (1 sec)

Attachments (1)

spawn.c-no-shell.patch (484 bytes) - added by glynn 8 years ago.
Don't use shell for spawning commands

Download all attachments as: .zip

Change History (54)

comment:1 in reply to:  description ; Changed 9 years ago by hellik

Replying to lponti:

wxgui g.mremove called on vector with * wildcard does not work:

I can confirm this (WinVista23-box).

but it's very interesting:

a first run of

g.mremove -f vect=map*

gets following

Unable to delete file 'C:\cygwin\home\andy/latlong/luigi/vector/mapBloomday_Olive_11set10_Avg/hist' 

there seems to be a problem with the hist-section of the Grass-vector-data-structure.

but in a second run of

g.mremove -f vect=map*

all vector maps marked by the *-wildcard are deleted.

Helmut

comment:2 in reply to:  1 ; Changed 9 years ago by hellik

Replying to hellik:

Replying to lponti:

wxgui g.mremove called on vector with * wildcard does not work:

I can confirm this (WinVista23-box).

but it's very interesting:

a first run of

g.mremove -f vect=map*

gets following

Unable to delete file 'C:\cygwin\home\andy/latlong/luigi/vector/mapBloomday_Olive_11set10_Avg/hist' 

there seems to be a problem with the hist-section of the Grass-vector-data-structure.

but in a second run of

g.mremove -f vect=map*

all vector maps marked by the *-wildcard are deleted.

Helmut

tested also with the latest wingrass65-nightly build. there also you need two runs of g.mremove -f to remove a vector map.

Helmut

comment:3 in reply to:  1 Changed 9 years ago by glynn

Replying to hellik:

but in a second run of

all vector maps marked by the *-wildcard are deleted.

Vect_open_old_head() is called if the dbln file exists. After deleting the table, the map is closed. Then all files are deleted from the directory.

I think that Vect_close() isn't closing all of the files, causing the unlink() to fail on Windows (on Unix, you can delete open files; on Windows, you can't).

I note that the history file is opened for both native and OGR maps, but is only closed for native maps. But I don't think that's the issue.

What would be an issue is if the database driver inherits the descriptor for the hist file, and is still running when Vect_delete() tries to delete the history file. I note that db_table_exists() doesn't shut down the driver if it returns an error indication.

comment:4 in reply to:  2 Changed 9 years ago by hellik

Replying to hellik:

Replying to hellik:

Replying to lponti:

wxgui g.mremove called on vector with * wildcard does not work:

I can confirm this (WinVista23-box).

but it's very interesting:

a first run of

g.mremove -f vect=map*

gets following

Unable to delete file 'C:\cygwin\home\andy/latlong/luigi/vector/mapBloomday_Olive_11set10_Avg/hist' 

there seems to be a problem with the hist-section of the Grass-vector-data-structure.

but in a second run of

g.mremove -f vect=map*

all vector maps marked by the *-wildcard are deleted.

Helmut

tested also with the latest wingrass65-nightly build. there also you need two runs of g.mremove -f to remove a vector map.

Helmut

also tested in a self built WinGrass7, this issue can be confirmed also be there.

Helmut

comment:5 Changed 9 years ago by Luigi Ponti

I was wondering whether this is actually a normal priority ticket. I gave it normal just because it is the default, but sounds like a fairly important command is affected. WinGRASS has been doing so much better recently, and I believe wild card-based removal of vector is an important component of GRASS shell scripts.

I routinely use a series of shell scripts that include the following GRASS commnands: g.parser, g.mapset, g.region, g.copy, g.mremove, v.in.ascii, v.extract, v.to.rast, v.proj, v.db.addcol, v.what.rast, v.voronoi, v.category, v.surf.idw, r.mapcalc, r.colors, r.report, r.univar, d.erase, d.rast, d.vect, d.his, d.grid, d.legend, d.text, d.mon, d.histogram.

Kind regards,

Luigi

comment:6 Changed 9 years ago by hamish

are wildcards from g.mlist working?

how about g.remove vect= for a single vector map?

Hamish

comment:7 in reply to:  6 Changed 9 years ago by Luigi Ponti

Replying to hamish:

are wildcards from g.mlist working?

Using self built (noticed that http://josef.fsv.cvut.cz/wingrass/ has not been updated in the last few days) releasebranch_6_4 revision: 43598. In North Carolina location, mapset user1:

GRASS 6.4> g.mlist type=vect pattern="bus*"
busroute1
busroute11
busroute6
busroute_a
busroutesall
busstopsall

how about g.remove vect= for a single vector map?

It works:

GRASS 6.4> g.copy vect=busroute1,routebus1
Copy vector <busroute1@PERMANENT> to current mapset as <routebus1>

GRASS 6.4> g.remove vect=routebus1         
Removing vector <routebus1>

It works with g.mremove -f with wildcard too:

GRASS 6.4> g.copy vect=busroute1,routebus1
Copy vector <busroute1@PERMANENT> to current mapset as <routebus1>

GRASS 6.4> g.mremove -f vect=route*
Removing vector <routebus1>

Has it been changed since 6.4.0-1? I assumed nothing had changed since the ticket was unmodified. Last report was from Helmut who confirmed about nine days ago in winGRASS 7.

Thanks,

Luigi

comment:8 Changed 9 years ago by Luigi Ponti

Still having the same issue using recent svn snapshopts: g.mremove needs to be run twice when used with wildcards to remove vectors.

I have g.mremove in a cleanup routine inside a bash script

cleanup()
{
	# Remove temp directory.
	\rm -rf $DIRTMP
        # Remove temp text files.
	\rm -f ~/clipRegion.txt
        #[...]
	# Remove gis temp files in latlong location
	g.mremove -f vect=map*
        #[...]
}

Currently using GRASS from installer WinGRASS-6.4.SVN-r43880-1-Setup.exe

Any hints appreciated. Thanks and regards,

Luigi

comment:9 Changed 9 years ago by Luigi Ponti

Priority: normalmajor

This also happens every time I use a command that has vector output using the --overwrite flag, and the output vector already exists, e.g.:

g.copy vect=streets_wake_large,streets_wake_large_tmp

First attempt does not work:

(Thu Oct 28 19:43:11 2010)                                                      
v.select --overwrite ainput=streets_wake_large binput=census_extract_all_trt2000 output=streets_wake_large_tmp
Vector map <streets_wake_large_tmp> already exists and will be overwritten
Unable to delete file 'C:\cygwin\home\andy/nc_spm_08/user1/vector/streets_wake_large_tmp/hist'
ERROR: Unable to delete vector map <streets_wake_large_tmp>
(Thu Oct 28 19:43:11 2010) Command finished (0 sec)                             

Second try is fine:

(Thu Oct 28 19:43:33 2010)                                                      
v.select --overwrite ainput=streets_wake_large binput=census_extract_all_trt2000 output=streets_wake_large_tmp
Vector map <streets_wake_large_tmp> already exists and will be overwritten
Processing features...
Processing areas...
Writing selected features...
Sto scrivendo gli attributi
Building topology for vector map <streets_wake_large_tmp>...
Registering primitives...
76 primitives registered
388 vertices registered
Building areas...
0 areas built
0 isles built
Attaching islands...
Attaching centroids...
Number of nodes: 77
Number of primitives: 76
Number of points: 0
Number of lines: 76
Number of boundaries: 0
Number of centroids: 0
Number of areas: 0
Number of isles: 0
v.select completo.
(Thu Oct 28 19:43:35 2010) Command finished (1 sec)

Maybe it is an issue of the OS: anybody able to reproduce it on XP? (I used same settings as my previous comment.)

Exactly the same thing happens when using g.remove on streets_wake_large_tmp as you need to run the command twice.

This would mean that the problem is not the wildcards.

I am changing priority to major because being unable to remove vectors seems a serious issue. Please, provide feedback on this.

Kind regards,

Luigi

comment:10 in reply to:  9 ; Changed 9 years ago by glynn

Replying to lponti:

I note that there haven't been any responses to comment:9.

I don't think that anything is going to happen on this until someone fires up a debugger and confirms or refutes that.

comment:11 in reply to:  10 ; Changed 9 years ago by glynn

Replying to glynn:

I note that there haven't been any responses to comment:9.

Oops. I mean comment:3.

comment:12 in reply to:  11 Changed 9 years ago by Luigi Ponti

Replying to glynn:

Replying to glynn:

I note that there haven't been any responses to comment:9.

Oops. I mean comment:3.

Thanks Glynn, and sorry for the inconvenience. I understand that reporting the same bug over and over is not going to fix it. Please, indicate if I can be of any further help or I should just be patient (and quiet). (Thanks for your patience and guidance along these years of GRASS learning.)

Luigi

comment:13 in reply to:  10 ; Changed 9 years ago by hellik

Replying to glynn:

Replying to lponti:

I note that there haven't been any responses to comment:9.

I don't think that anything is going to happen on this until someone fires up a debugger and confirms or refutes that.

g.list type=vect mapset=deletevectors                                           
----------------------------------------------
vector Dateien im Mapset <deletevectors> vorhanden:
busroute1 busroute2 busroute3

first run

g.mremove -f vect=bus*                                                          
Entferne vector <busroute1>.
'vector/busroute1' wurde in mehreren Mapsets gefunden (auch gefunden in <PERMANENT>).
Verwende <busroute1@deletevectors>
D3/3: Delete vector 'busroute1'
D1/3: dbln file: C:\gisdata\grassdata/nc_spm_08/deletevector
s/vector/busroute1/dbln
D1/3: Vect_open_old(): name = busroute1 mapset=
deletevectors update = 0
D1/3: Vect_set_thresh(): thresh = 0.000000
D3/3: dig_init_plus()
D1/3: dig_spidx_init()
D3/3: dig_cidx_init()
D1/3: open format file:
'deletevectors/vector/busroute1/frmt'
D1/3: Vector format: 0 (native)
D1/3: Vect_set_thresh(): thresh = 0.000000
D1/3: Vect__read_head(): vector = busroute1@deletevectors
D1/3: Vect_set_thresh(): thresh = 0.000000
D1/3: Level request = 1
D1/3: Vect_open_old(): vector opened on level 1
D1/3: Vect_read_dblinks(): map = busroute1, mapset =
deletevectors
D3/3: Searching for FID column in OGR DB
D1/3: dbln file: C:\gisdata\grassdata/nc_spm_08/deletevector
s/vector/busroute1/dbln
D1/3: dbln: 1 busroute1 cat
$GISDBASE/$LOCATION_NAME/$MAPSET/dbf/ dbf
D3/3: Field number <1>, name <(null)>
D3/3: Vect_check_dblink: field 1
D1/3: field = 1 name = (null), table = busroute1, key = cat,
database = $GISDBASE/$LOCATION_NAME/$MAPSET/dbf/, driver =
dbf
D1/3: Dblinks read
D1/3: Vect_get_dblink(): link = 0
D3/3: Vect_subst_var(): in =
$GISDBASE/$LOCATION_NAME/$MAPSET/dbf/, map = busroute1,
mapset = deletevectors
D3/3:   -> C:\gisdata\grassdata/nc_spm_08/deletevectors/dbf/
D3/3: Delete drv:db:table 'dbf:C:\gisdata\grassdata/nc_spm_0
8/deletevectors/dbf/:busroute1'
D3/3: db_start_driver_open_database():
  drvname = dbf, dbname =
C:\gisdata\grassdata/nc_spm_08/deletevectors/dbf/
D2/3: dbDbmscap(): opendir [c:\Program
Files\GRASS-64-SVN\driver\db\]
D3/3: win_spawn: args = C:\windows\system32\cmd.exe /c
""c:\Program Files\GRASS-64-SVN\driver\db\dbf.exe""
D2/3: DBF: db__driver_open_database() name =
'C:\gisdata\grassdata/nc_spm_08/deletevectors/dbf/'
D2/3: db.name =
C:\gisdata\grassdata/nc_spm_08/deletevectors/dbf/
D2/3: add_table(): table = busroute1 name = busroute1.dbf
D2/3: add_table(): table = busroute2 name = busroute2.dbf
D2/3: add_table(): table = busroute3 name = busroute3.dbf
D2/3: table = busroute1 -> busroute1
D2/3: save_table 0
D2/3: save_table 1
D2/3: save_table 2
D3/3: db_delete_table(): driver = dbf, db =
C:\gisdata\grassdata/nc_spm_08/deletevectors/dbf/, table =
busroute1
D2/3: dbDbmscap(): opendir [c:\Program
Files\GRASS-64-SVN\driver\db\]
D3/3: win_spawn: args = C:\windows\system32\cmd.exe /c
""c:\Program Files\GRASS-64-SVN\driver\db\dbf.exe""
D2/3: DBF: db__driver_open_database() name =
'C:\gisdata\grassdata/nc_spm_08/deletevectors/dbf/'
D2/3: db.name =
C:\gisdata\grassdata/nc_spm_08/deletevectors/dbf/
D2/3: add_table(): table = busroute1 name = busroute1.dbf
D2/3: add_table(): table = busroute2 name = busroute2.dbf
D2/3: add_table(): table = busroute3 name = busroute3.dbf
D3/3: drop table busroute1
D3/3: SQL statement parsed successfully: drop table
busroute1
D2/3: find_table(): table = busroute1
D2/3:   ? busroute1
D2/3: load_table_head(): tab = 0, C:\gisdata\grassdata/nc_sp
m_08/deletevectors/dbf//busroute1.dbf
D2/3:   ncols = 2
D2/3:   DBFFieldType 1
D3/3: add_column(): tab = 0, type = 2, name = cat, width =
11, decimals = 0
D2/3:   DBFFieldType 0
D3/3: add_column(): tab = 0, type = 1, name = ROUTE, width =
5, decimals = 0
D3/3: Doing SQL command <2> on DBF table... (see
include/sqlp.h)
D2/3: save_table 0
D2/3: save_table 1
D2/3: save_table 2
D1/3: Vect_close(): name = busroute1, mapset =
deletevectors, format = 0, level = 1
D1/3: close history file
D3/3: opendir 'C:\gisdata\grassdata/nc_spm_08/deletevectors/
vector/busroute1'
D3/3: file = '.'
D3/3: file = '..'
D3/3: file = 'cidx'
D3/3: delete file 'C:\gisdata\grassdata/nc_spm_08/deletevect
ors/vector/busroute1/cidx'
D3/3: file = 'coor'
D3/3: delete file 'C:\gisdata\grassdata/nc_spm_08/deletevect
ors/vector/busroute1/coor'
D3/3: file = 'dbln'
D3/3: delete file 'C:\gisdata\grassdata/nc_spm_08/deletevect
ors/vector/busroute1/dbln'
D3/3: file = 'head'
D3/3: delete file 'C:\gisdata\grassdata/nc_spm_08/deletevect
ors/vector/busroute1/head'
D3/3: file = 'hist'
D3/3: delete file 'C:\gisdata\grassdata/nc_spm_08/deletevect
ors/vector/busroute1/hist'
D3/3: file = 'topo'
D3/3: delete file 'C:\gisdata\grassdata/nc_spm_08/deletevect
ors/vector/busroute1/topo'
D3/3: rename 'C:\gisdata\grassdata/nc_spm_08/deletevectors/v
ector/busroute1' to
'C:\gisdata\grassdata/nc_spm_08/deletevectors/.tmp/3728.0'
D3/3: remove directory
'C:\gisdata\grassdata/nc_spm_08/deletevectors/.tmp/3728.0'
Entferne vector <busroute2>.
D3/3: Delete vector 'busroute2'
D1/3: dbln file: C:\gisdata\grassdata/nc_spm_08/deletevector
s/vector/busroute2/dbln
D1/3: Vect_open_old(): name = busroute2 mapset=
deletevectors update = 0
D1/3: Vect_set_thresh(): thresh = 0.000000
D3/3: dig_init_plus()
D1/3: dig_spidx_init()
D3/3: dig_cidx_init()
D1/3: open format file:
'deletevectors/vector/busroute2/frmt'
D1/3: Vector format: 0 (native)
D1/3: Vect_set_thresh(): thresh = 0.000000
D1/3: Vect__read_head(): vector = busroute2@deletevectors
D1/3: Vect_set_thresh(): thresh = 0.000000
D1/3: Level request = 1
D1/3: Vect_open_old(): vector opened on level 1
D1/3: Vect_read_dblinks(): map = busroute2, mapset =
deletevectors
D3/3: Searching for FID column in OGR DB
D1/3: dbln file: C:\gisdata\grassdata/nc_spm_08/deletevector
s/vector/busroute2/dbln
D1/3: dbln: 1 busroute2 cat
$GISDBASE/$LOCATION_NAME/$MAPSET/dbf/ dbf
D3/3: Field number <1>, name <(null)>
D3/3: Vect_check_dblink: field 1
D1/3: field = 1 name = (null), table = busroute2, key = cat,
database = $GISDBASE/$LOCATION_NAME/$MAPSET/dbf/, driver =
dbf
D1/3: Dblinks read
D1/3: Vect_get_dblink(): link = 0
D3/3: Vect_subst_var(): in =
$GISDBASE/$LOCATION_NAME/$MAPSET/dbf/, map = busroute2,
mapset = deletevectors
D3/3:   -> C:\gisdata\grassdata/nc_spm_08/deletevectors/dbf/
D3/3: Delete drv:db:table 'dbf:C:\gisdata\grassdata/nc_spm_0
8/deletevectors/dbf/:busroute2'
D3/3: db_start_driver_open_database():
  drvname = dbf, dbname =
C:\gisdata\grassdata/nc_spm_08/deletevectors/dbf/
D2/3: dbDbmscap(): opendir [c:\Program
Files\GRASS-64-SVN\driver\db\]
D3/3: win_spawn: args = C:\windows\system32\cmd.exe /c
""c:\Program Files\GRASS-64-SVN\driver\db\dbf.exe""
D2/3: DBF: db__driver_open_database() name =
'C:\gisdata\grassdata/nc_spm_08/deletevectors/dbf/'
D2/3: db.name =
C:\gisdata\grassdata/nc_spm_08/deletevectors/dbf/
D2/3: add_table(): table = busroute2 name = busroute2.dbf
D2/3: add_table(): table = busroute3 name = busroute3.dbf
D2/3: table = busroute2 -> busroute2
D2/3: save_table 0
D2/3: save_table 1
D3/3: db_delete_table(): driver = dbf, db =
C:\gisdata\grassdata/nc_spm_08/deletevectors/dbf/, table =
busroute2
D2/3: dbDbmscap(): opendir [c:\Program
Files\GRASS-64-SVN\driver\db\]
D3/3: win_spawn: args = C:\windows\system32\cmd.exe /c
""c:\Program Files\GRASS-64-SVN\driver\db\dbf.exe""
D2/3: DBF: db__driver_open_database() name =
'C:\gisdata\grassdata/nc_spm_08/deletevectors/dbf/'
D2/3: db.name =
C:\gisdata\grassdata/nc_spm_08/deletevectors/dbf/
D2/3: add_table(): table = busroute2 name = busroute2.dbf
D2/3: add_table(): table = busroute3 name = busroute3.dbf
D3/3: drop table busroute2
D3/3: SQL statement parsed successfully: drop table
busroute2
D2/3: find_table(): table = busroute2
D2/3:   ? busroute2
D2/3: load_table_head(): tab = 0, C:\gisdata\grassdata/nc_sp
m_08/deletevectors/dbf//busroute2.dbf
D2/3:   ncols = 2
D2/3:   DBFFieldType 1
D3/3: add_column(): tab = 0, type = 2, name = cat, width =
11, decimals = 0
D2/3:   DBFFieldType 0
D3/3: add_column(): tab = 0, type = 1, name = ROUTE, width =
5, decimals = 0
D3/3: Doing SQL command <2> on DBF table... (see
include/sqlp.h)
D2/3: save_table 0
D2/3: save_table 1
D1/3: Vect_close(): name = busroute2, mapset =
deletevectors, format = 0, level = 1
D1/3: close history file
D3/3: opendir 'C:\gisdata\grassdata/nc_spm_08/deletevectors/
vector/busroute2'
D3/3: file = '.'
D3/3: file = '..'
D3/3: file = 'cidx'
D3/3: delete file 'C:\gisdata\grassdata/nc_spm_08/deletevect
ors/vector/busroute2/cidx'
D3/3: file = 'coor'
D3/3: delete file 'C:\gisdata\grassdata/nc_spm_08/deletevect
ors/vector/busroute2/coor'
D3/3: file = 'dbln'
D3/3: delete file 'C:\gisdata\grassdata/nc_spm_08/deletevect
ors/vector/busroute2/dbln'
D3/3: file = 'head'
D3/3: delete file 'C:\gisdata\grassdata/nc_spm_08/deletevect
ors/vector/busroute2/head'
D3/3: file = 'hist'
D3/3: delete file 'C:\gisdata\grassdata/nc_spm_08/deletevect
ors/vector/busroute2/hist'
Kann Datei 'C:\gisdata\grassdata/nc_spm_08/deletevectors/vector/busroute2/hist' nicht löschen.
konnte nicht entfernt werden.
<busroute2> nichts gelöscht.
Entferne vector <busroute3>.
D3/3: Delete vector 'busroute3'
D1/3: dbln file: C:\gisdata\grassdata/nc_spm_08/deletevector
s/vector/busroute3/dbln
D1/3: Vect_open_old(): name = busroute3 mapset=
deletevectors update = 0
D1/3: Vect_set_thresh(): thresh = 0.000000
D3/3: dig_init_plus()
D1/3: dig_spidx_init()
D3/3: dig_cidx_init()
D1/3: open format file:
'deletevectors/vector/busroute3/frmt'
D1/3: Vector format: 0 (native)
D1/3: Vect_set_thresh(): thresh = 0.000000
D1/3: Vect__read_head(): vector = busroute3@deletevectors
D1/3: Vect_set_thresh(): thresh = 0.000000
D1/3: Level request = 1
D1/3: Vect_open_old(): vector opened on level 1
D1/3: Vect_read_dblinks(): map = busroute3, mapset =
deletevectors
D3/3: Searching for FID column in OGR DB
D1/3: dbln file: C:\gisdata\grassdata/nc_spm_08/deletevector
s/vector/busroute3/dbln
D1/3: dbln: 1 busroute3 cat
$GISDBASE/$LOCATION_NAME/$MAPSET/dbf/ dbf
D3/3: Field number <1>, name <(null)>
D3/3: Vect_check_dblink: field 1
D1/3: field = 1 name = (null), table = busroute3, key = cat,
database = $GISDBASE/$LOCATION_NAME/$MAPSET/dbf/, driver =
dbf
D1/3: Dblinks read
D1/3: Vect_get_dblink(): link = 0
D3/3: Vect_subst_var(): in =
$GISDBASE/$LOCATION_NAME/$MAPSET/dbf/, map = busroute3,
mapset = deletevectors
D3/3:   -> C:\gisdata\grassdata/nc_spm_08/deletevectors/dbf/
D3/3: Delete drv:db:table 'dbf:C:\gisdata\grassdata/nc_spm_0
8/deletevectors/dbf/:busroute3'
D3/3: db_start_driver_open_database():
  drvname = dbf, dbname =
C:\gisdata\grassdata/nc_spm_08/deletevectors/dbf/
D2/3: dbDbmscap(): opendir [c:\Program
Files\GRASS-64-SVN\driver\db\]
D3/3: win_spawn: args = C:\windows\system32\cmd.exe /c
""c:\Program Files\GRASS-64-SVN\driver\db\dbf.exe""
D2/3: DBF: db__driver_open_database() name =
'C:\gisdata\grassdata/nc_spm_08/deletevectors/dbf/'
D2/3: db.name =
C:\gisdata\grassdata/nc_spm_08/deletevectors/dbf/
D2/3: add_table(): table = busroute3 name = busroute3.dbf
D2/3: table = busroute3 -> busroute3
D2/3: save_table 0
D3/3: db_delete_table(): driver = dbf, db =
C:\gisdata\grassdata/nc_spm_08/deletevectors/dbf/, table =
busroute3
D2/3: dbDbmscap(): opendir [c:\Program
Files\GRASS-64-SVN\driver\db\]
D3/3: win_spawn: args = C:\windows\system32\cmd.exe /c
""c:\Program Files\GRASS-64-SVN\driver\db\dbf.exe""
D2/3: DBF: db__driver_open_database() name =
'C:\gisdata\grassdata/nc_spm_08/deletevectors/dbf/'
D2/3: db.name =
C:\gisdata\grassdata/nc_spm_08/deletevectors/dbf/
D2/3: add_table(): table = busroute3 name = busroute3.dbf
D3/3: drop table busroute3
D3/3: SQL statement parsed successfully: drop table
busroute3
D2/3: find_table(): table = busroute3
D2/3:   ? busroute3
D2/3: load_table_head(): tab = 0, C:\gisdata\grassdata/nc_sp
m_08/deletevectors/dbf//busroute3.dbf
D2/3:   ncols = 2
D2/3:   DBFFieldType 1
D3/3: add_column(): tab = 0, type = 2, name = cat, width =
11, decimals = 0
D2/3:   DBFFieldType 0
D3/3: add_column(): tab = 0, type = 1, name = ROUTE, width =
5, decimals = 0
D3/3: Doing SQL command <2> on DBF table... (see
include/sqlp.h)
D2/3: save_table 0
D1/3: Vect_close(): name = busroute3, mapset =
deletevectors, format = 0, level = 1
D1/3: close history file
D3/3: opendir 'C:\gisdata\grassdata/nc_spm_08/deletevectors/
vector/busroute3'
D3/3: file = '.'
D3/3: file = '..'
D3/3: file = 'cidx'
D3/3: delete file 'C:\gisdata\grassdata/nc_spm_08/deletevect
ors/vector/busroute3/cidx'
D3/3: file = 'coor'
D3/3: delete file 'C:\gisdata\grassdata/nc_spm_08/deletevect
ors/vector/busroute3/coor'
D3/3: file = 'dbln'
D3/3: delete file 'C:\gisdata\grassdata/nc_spm_08/deletevect
ors/vector/busroute3/dbln'
D3/3: file = 'head'
D3/3: delete file 'C:\gisdata\grassdata/nc_spm_08/deletevect
ors/vector/busroute3/head'
D3/3: file = 'hist'
D3/3: delete file 'C:\gisdata\grassdata/nc_spm_08/deletevect
ors/vector/busroute3/hist'
Kann Datei 'C:\gisdata\grassdata/nc_spm_08/deletevectors/vector/busroute3/hist' nicht löschen.
konnte nicht entfernt werden.
<busroute3> nichts gelöscht.

second run

g.mremove -f vect=bus*                                                          
Entferne vector <busroute2>.
D3/3: Delete vector 'busroute2'
D1/3: dbln file: C:\gisdata\grassdata/nc_spm_08/deletevector
s/vector/busroute2/dbln
D3/3: opendir 'C:\gisdata\grassdata/nc_spm_08/deletevectors/
vector/busroute2'
D3/3: file = '.'
D3/3: file = '..'
D3/3: file = 'hist'
D3/3: delete file 'C:\gisdata\grassdata/nc_spm_08/deletevect
ors/vector/busroute2/hist'
D3/3: file = 'topo'
D3/3: delete file 'C:\gisdata\grassdata/nc_spm_08/deletevect
ors/vector/busroute2/topo'
D3/3: rename 'C:\gisdata\grassdata/nc_spm_08/deletevectors/v
ector/busroute2' to
'C:\gisdata\grassdata/nc_spm_08/deletevectors/.tmp/7964.0'
D3/3: remove directory
'C:\gisdata\grassdata/nc_spm_08/deletevectors/.tmp/7964.0'
Entferne vector <busroute3>.
D3/3: Delete vector 'busroute3'
D1/3: dbln file: C:\gisdata\grassdata/nc_spm_08/deletevector
s/vector/busroute3/dbln
D3/3: opendir 'C:\gisdata\grassdata/nc_spm_08/deletevectors/
vector/busroute3'
D3/3: file = '.'
D3/3: file = '..'
D3/3: file = 'hist'
D3/3: delete file 'C:\gisdata\grassdata/nc_spm_08/deletevect
ors/vector/busroute3/hist'
Kann Datei 'C:\gisdata\grassdata/nc_spm_08/deletevectors/vector/busroute3/hist' nicht löschen.
konnte nicht entfernt werden.
<busroute3> nichts gelöscht.

Helmut

comment:14 in reply to:  13 ; Changed 9 years ago by glynn

Replying to hellik:

I don't think that anything is going to happen on this until someone fires up a debugger and confirms or refutes that.

Setting DEBUG= won't be enough. Someone will need to use gdb to track what's actually going on. I.e. when the hist file is opened, and when it gets closed. Setting breakpoints on open() and fclose() (not a typo; the hist file is opened with G_fopen_*, which use open()+fdopen(), but closed with fclose()).

comment:15 in reply to:  14 ; Changed 9 years ago by hellik

Replying to glynn:

Replying to hellik:

I don't think that anything is going to happen on this until someone fires up a debugger and confirms or refutes that.

Setting DEBUG= won't be enough. Someone will need to use gdb to track what's actually going on. I.e. when the hist file is opened, and when it gets closed. Setting breakpoints on open() and fclose() (not a typo; the hist file is opened with G_fopen_*, which use open()+fdopen(), but closed with fclose()).

any hints for setting breakpoints? in the wiki (http://grass.osgeo.org/wiki/GRASS_Debugging#Using_GDB) there aren't any hints.

Helmut

comment:16 in reply to:  6 Changed 9 years ago by lutra

how about g.remove vect= for a single vector map?

it doesn't work, see

http://lists.osgeo.org/pipermail/grass-user/2010-November/058600.html

comment:17 Changed 9 years ago by neteler

Summary: g.mremove fails when used with wildcard in WinGRASS-6.4.0-1g.mremove fails when used with wildcard on Windows + needs to be used twice

comment:18 Changed 9 years ago by neteler

From #1210: To delete a vector map from a mapset I have to do the operation twice (OSGeo4W)

comment:19 Changed 9 years ago by hellik

Keywords: wingrass added

comment:20 Changed 9 years ago by hellik

see also from qgis:

"GRASS toolbox: error removing vectors from a mapset under Windows" https://trac.osgeo.org/qgis/ticket/3646

comment:21 Changed 9 years ago by hellik

Priority: majorcritical

tested with WinGRASS-6.4.SVN-r45757-1-Setup.exe

g.remove vect=myfire@user1                                                      
Removing vector <myfire@user1>
Kann Datei 'C:\gisdata\grassdata/nc_spm_08/user1/vector/myfire/hist' nicht löschen.
couldn't be removed
<myfire> nothing removed
(Sun Mar 27 17:47:12 2011) Command finished (0 sec)                             
(Sun Mar 27 17:47:13 2011)                                                      
g.remove vect=myfire@user1                                                      
Removing vector <myfire@user1>

comment:22 in reply to:  15 Changed 9 years ago by hellik

Replying to hellik:

any hints for setting breakpoints? in the wiki (http://grass.osgeo.org/wiki/GRASS_Debugging#Using_GDB) there aren't any hints.

any hints?

comment:23 Changed 9 years ago by marisn

CPU: x86-32Unspecified
Keywords: v.in.ogr v.select g.remove added
Summary: g.mremove fails when used with wildcard on Windows + needs to be used twiceRemoving vector map in Windows fails with "Unable to delete vector map"

I changed bug summary to better reflect it's scope.

It affects also v.in.ogr removal of temporary files (coor and not hist file). Bug #1303

comment:24 Changed 9 years ago by martinl

Milestone: 6.4.16.4.2
Priority: criticalblocker

comment:25 in reply to:  23 ; Changed 9 years ago by mmetz

Replying to marisn:

I changed bug summary to better reflect it's scope.

It affects also v.in.ogr removal of temporary files (coor and not hist file). Bug #1303

Hopefully fixed for devbr in r46041.

Vect_delete() uses unlink(), whereas raster and all other files are removed by remove(): the file will remain in existence until the last file descriptor referring to it is closed (at least on Linux). In Vect_delete(), I have replaced unlink() with remove(), working on Linux, awaits testing on Windows.

Markus M

comment:26 in reply to:  25 Changed 9 years ago by hellik

Replying to mmetz:

Replying to marisn:

I changed bug summary to better reflect it's scope.

It affects also v.in.ogr removal of temporary files (coor and not hist file). Bug #1303

Hopefully fixed for devbr in r46041.

tested with WinGRASS-6.5.SVN-r46045-1-Setup.exe

g.remove vect=mygeology@user1                                                   
Removing vector <mygeology@user1>
Unable to delete file 'J:\gisdata/nc_spm_08/user1/vector/mygeology/hist'. Reason: Permission denied
couldn't be removed
<mygeology> nothing removed
(Wed Apr 20 09:59:46 2011) Command finished (0 sec)                             
(Wed Apr 20 09:59:47 2011)                                                      
g.remove vect=mygeology@user1                                                   
Removing vector <mygeology@user1>
(Wed Apr 20 09:59:48 2011) Command finished (0 sec)   

Helmut

comment:27 in reply to:  25 ; Changed 9 years ago by glynn

Replying to mmetz:

Hopefully fixed for devbr in r46041.

Vect_delete() uses unlink(), whereas raster and all other files are removed by remove(): the file will remain in existence until the last file descriptor referring to it is closed (at least on Linux). In Vect_delete(), I have replaced unlink() with remove(), working on Linux, awaits testing on Windows.

I'm fairly sure that r46041 has no effect. On Unix, the difference between remove() and unlink() is that remove() handles both files and directories; it calls unlink() for files and rmdir() for directories. unlink() only works on files.

The "garbage-collecting" behaviour (a file is removed when it has no links and no process has it open) always applies. There is no way to force deletion of a file which is open, or to remove all links to a file (there may exist links in directories on which the process lacks write permission, in directories which are inaccessible due to having another filesystem mounted over them, etc).

On Windows, I can't discern any difference between unlink() and remove(). Unlike Unix, remove() only works for files. And unlike Unix, you can't "unlink" a file which is open; the unlink/remove call fails with EACCESS.

comment:28 in reply to:  27 ; Changed 9 years ago by mmetz

Replying to glynn:

Replying to mmetz:

Hopefully fixed for devbr in r46041.

Vect_delete() uses unlink(), whereas raster and all other files are removed by remove(): the file will remain in existence until the last file descriptor referring to it is closed (at least on Linux). In Vect_delete(), I have replaced unlink() with remove(), working on Linux, awaits testing on Windows.

I'm fairly sure that r46041 has no effect. On Unix, the difference between remove() and unlink() is that remove() handles both files and directories; it calls unlink() for files and rmdir() for directories. unlink() only works on files.

The "garbage-collecting" behaviour (a file is removed when it has no links and no process has it open) always applies. There is no way to force deletion of a file which is open, or to remove all links to a file (there may exist links in directories on which the process lacks write permission, in directories which are inaccessible due to having another filesystem mounted over them, etc).

On Windows, I can't discern any difference between unlink() and remove(). Unlike Unix, remove() only works for files. And unlike Unix, you can't "unlink" a file which is open; the unlink/remove call fails with EACCESS.

None of the files making up a native GRASS vector should be still open when they are to be deleted. Some of them may have been opened and closed recently (a few lines of code further up in Vect_delete()), but I am pretty sure that they are all closed, otherwise g.remove should never work. Maybe fclose() does not close a file stream now, but sometime soon (e.g. busy flushing buffers), and 'soon' is sometimes too late?

comment:29 in reply to:  28 ; Changed 9 years ago by glynn

Replying to mmetz:

None of the files making up a native GRASS vector should be still open when they are to be deleted.

I know that they shouldn't be open, but are they? See comment:3.

I am pretty sure that they are all closed, otherwise g.remove should never work.

But g.remove doesn't work.

Well, it works on Unix, as it's perfectly valid to remove a file which is open (remove() and unlink() just remove the filename; the file itself will be removed once there are no more links and no process has it open).

And it works on Windows if you use it to remove a half-deleted map. In this case, the history file never gets opened in the first place.

But it doesn't work on Windows if you try to remove a valid map.

Maybe fclose() does not close a file stream now, but sometime soon (e.g. busy flushing buffers), and 'soon' is sometimes too late?

No; fclose() doesn't return until the underlying file is actually closed. Lots of code would break if this wasn't the case, as it's quite common to delete or rename a file immediately after fclose() (on Windows, you can't rename an open file).

comment:30 in reply to:  29 ; Changed 9 years ago by mmetz

Replying to glynn:

Replying to mmetz:

None of the files making up a native GRASS vector should be still open when they are to be deleted.

I know that they shouldn't be open, but are they? See comment:3.

OK. I suggest Vect__open_old() and Vect_open_new() should initialize all file pointers to NULL and Vect_close() should close anything that is not NULL.

These changes should IMHO first be done in trunk, then backported.

I am pretty sure that they are all closed, otherwise g.remove should never work.

But g.remove doesn't work.

... on the first run on Windows when using the wxGUI. BTW, it does work for me just fine on Windows using the TclTk GUI.

Well, it works on Unix, as it's perfectly valid to remove a file which is open (remove() and unlink() just remove the filename; the file itself will be removed once there are no more links and no process has it open).

And it works on Windows if you use it to remove a half-deleted map. In this case, the history file never gets opened in the first place.

But it doesn't work on Windows if you try to remove a valid map.

IOW, if Vect_close() is called before the files are to be removed.

comment:31 in reply to:  30 ; Changed 9 years ago by martinl

Replying to mmetz:

OK. I suggest Vect__open_old() and Vect_open_new() should initialize all file pointers to NULL and Vect_close() should close anything that is not NULL.

it's already in trunk grass/trunk/lib/vector/Vlib/open.c#L165

comment:32 in reply to:  31 ; Changed 9 years ago by martinl

Replying to martinl:

Replying to mmetz:

OK. I suggest Vect__open_old() and Vect_open_new() should initialize all file pointers to NULL and Vect_close() should close anything that is not NULL.

it's already in trunk grass/trunk/lib/vector/Vlib/open.c#L165

...only referring to Vect__open_old()

comment:33 in reply to:  32 Changed 9 years ago by mmetz

Replying to martinl:

Replying to martinl:

Replying to mmetz:

OK. I suggest Vect__open_old() and Vect_open_new() should initialize all file pointers to NULL and Vect_close() should close anything that is not NULL.

it's already in trunk grass/trunk/lib/vector/Vlib/open.c#L165

...only referring to Vect__open_old()

Unfortunately, G_zero() does not set all contents of the Map_info structure to 0 or NULL; that's the reason for the existence of line 180 in open.c [grass/trunk/lib/vector/Vlib/open.c#L180]

comment:34 in reply to:  30 ; Changed 9 years ago by glynn

Replying to mmetz:

I know that they shouldn't be open, but are they? See comment:3.

OK. I suggest Vect__open_old() and Vect_open_new() should initialize all file pointers to NULL and Vect_close() should close anything that is not NULL.

That won't help if the problem is being caused by the DBMI driver inheriting the descriptor and not terminating before the file is deleted. I don't know if this is what's causing the problem, but there appear to be cases where it can happen.

Unfortunately, G_zero() does not set all contents of the Map_info structure to 0 or NULL

How come?

comment:35 in reply to:  34 ; Changed 9 years ago by mmetz

Replying to glynn:

Replying to mmetz:

I know that they shouldn't be open, but are they? See comment:3.

OK. I suggest Vect__open_old() and Vect_open_new() should initialize all file pointers to NULL and Vect_close() should close anything that is not NULL.

That won't help if the problem is being caused by the DBMI driver inheriting the descriptor and not terminating before the file is deleted. I don't know if this is what's causing the problem, but there appear to be cases where it can happen.

The DBMI driver, at least the way it is called by Vect_delete(), does not inherit any file pointers, it gets only the names of the driver, database, and table.

The only two file pointers in the map_info structure are those for the hist and the coor file, and so far only these two files gave problems, but not dbln, cidx, sidx, topo. Coincidence? Vect_close() does indeed close the file pointers for hist and coor, I tested.

Unfortunately, G_zero() does not set all contents of the Map_info structure to 0 or NULL

How come?

Can't reproduce any more, please ignore.

comment:36 in reply to:  35 ; Changed 9 years ago by glynn

Replying to mmetz:

The DBMI driver, at least the way it is called by Vect_delete(), does not inherit any file pointers, it gets only the names of the driver, database, and table.

A process doesn't inherit "file pointers", it inherits either descriptors (Unix) or handles (Windows). On Unix, a child process inherits all of its parent's descriptors. On Windows, the situation is more complex: the CreateProcess() function has a parameter, bInheritHandles, which specifies whether inheritable handles are inherited by the child process (inheritability is a property of a handle).

The Windows version of G_spawn_ex (which db_start_driver uses) sets the bInheritHandles parameter to 1, as this is required in order to be able to set std{in,out,err} for the child process (STARTF_USESTDHANDLES flag in the STARTUPINFO structure). So the child process will inherit any inheritable handles.

However, I don't know whether the handles which underlie the descriptors returned by open() etc are inheritable. If they are, the DBMI driver process will inherit the underlying handles from the parent, meaning that the corresponding file cannot be deleted, renamed, etc while the driver is running.

It should be possible to determine what is actually happening by making the driver sleep() long enough so that it can be inspected with e.g. Process Explorer.

comment:37 in reply to:  36 ; Changed 8 years ago by mmetz

Replying to glynn:

Replying to mmetz:

The DBMI driver, at least the way it is called by Vect_delete(), does not inherit any file pointers, it gets only the names of the driver, database, and table.

A process doesn't inherit "file pointers", it inherits either descriptors (Unix) or handles (Windows). On Unix, a child process inherits all of its parent's descriptors. On Windows, the situation is more complex: the CreateProcess() function has a parameter, bInheritHandles, which specifies whether inheritable handles are inherited by the child process (inheritability is a property of a handle).

The Windows version of G_spawn_ex (which db_start_driver uses) sets the bInheritHandles parameter to 1, as this is required in order to be able to set std{in,out,err} for the child process (STARTF_USESTDHANDLES flag in the STARTUPINFO structure). So the child process will inherit any inheritable handles.

However, I don't know whether the handles which underlie the descriptors returned by open() etc are inheritable. If they are, the DBMI driver process will inherit the underlying handles from the parent, meaning that the corresponding file cannot be deleted, renamed, etc while the driver is running.

I had the opportunity to test 6.4.2 on xp using v.in.ascii and noticed that the DBMI driver, in this case dbf, remains open and is not closed. Even manual deletion of the affected files does not work because they are still used by the DBMI driver. The files could be deleted only after manually killing the DBMI driver. BTW, the DBMI driver kept running after closing GRASS and any msys consoles.

So does this mean that the DBMI driver is not properly closed?

Markus M

comment:38 in reply to:  37 ; Changed 8 years ago by glynn

Replying to mmetz:

So does this mean that the DBMI driver is not properly closed?

It certainly looks that way. Even if the client doesn't send DB_PROC_SHUTDOWN_DRIVER, the driver should get EOF on its stdin when the client terminates.

Can you use e.g. Process Explorer and/or gdb to discover anything about the state of the driver process after the client terminates?

comment:39 in reply to:  38 ; Changed 8 years ago by mmetz

Replying to glynn:

Replying to mmetz:

So does this mean that the DBMI driver is not properly closed?

It certainly looks that way. Even if the client doesn't send DB_PROC_SHUTDOWN_DRIVER, the driver should get EOF on its stdin when the client terminates.

Can you use e.g. Process Explorer and/or gdb to discover anything about the state of the driver process after the client terminates?

Testing the same 6.4.2 installer on a different xp system, the DBMI driver is always closed. Weird. But removing a vector fails 9 out of 10 times, sometimes it succeeds. Since the driver is closed, I can not investigate it with e.g. Process Explorer. The driver remains open if I disable DB_START_PROCEDURE_CALL(DB_PROC_SHUTDOWN_DRIVER) in db_shutdown_driver(), so that seems to work.

Removing a vector always succeeds if I insert Sleep() (Uppercase Sleep) for some few hundred milliseconds in db_shutdown_driver(), after _cwait() is called. I am not sure if this is a solution or just a workaround.

BTW, driver->pid refers to the PID of the instance of cmd.exe associated with the driver, e.g. dbf.exe, not the PID of dbf.exe itself, but that does not seem to cause problems.

Markus M

Changed 8 years ago by glynn

Attachment: spawn.c-no-shell.patch added

Don't use shell for spawning commands

comment:40 in reply to:  39 ; Changed 8 years ago by glynn

Replying to mmetz:

The driver remains open if I disable DB_START_PROCEDURE_CALL(DB_PROC_SHUTDOWN_DRIVER) in db_shutdown_driver()

That's not good; the EOF when the client terminates should be enough. But that's another problem.

Removing a vector always succeeds if I insert Sleep() (Uppercase Sleep) for some few hundred milliseconds in db_shutdown_driver(), after _cwait() is called. I am not sure if this is a solution or just a workaround.

Can you try modifying lib/db/dbmi_client/shutdown.c to use G_wait() instead of _cwait()? _cwait() is only defined as working with process IDs returned from the _spawn functions, which are no longer used.

BTW, driver->pid refers to the PID of the instance of cmd.exe associated with the driver, e.g. dbf.exe, not the PID of dbf.exe itself, but that does not seem to cause problems.

For testing, it might help to apply attachment:spawn.c-no-shell.patch . That can't be applied generally, as it will prevent G_spawn[_ex] from working with scripts, but it may make it easier to deal with this specific issue. For the general case, we might want to disable the use of a shell if the program name ends in ".exe", or we might need to add a SF_SHELL (or SF_NO_SHELL) flag.

comment:41 Changed 8 years ago by lutra

Hi all, I'm mainly a GRASS user trough QGIS and I would like to underline that in QGIS 1.5, that was shipped with a GRASS 6.4 RC revision (should not be hard to check exactly what revision was used), this issue was not present, I just tested again.

Moreover also this

http://hub.qgis.org/issues/3648

was not present (this is actually a issue that makes GRASS unusable under QGIS >= 1.6) and that may be was fixed with

http://trac.osgeo.org/grass/changeset/47519

unfortunately is not yet possible to confirm the fix as we still don't have GRASS svn in the OSGeo4W installer.

Cheers

comment:42 in reply to:  40 ; Changed 8 years ago by mmetz

Replying to glynn:

Can you try modifying lib/db/dbmi_client/shutdown.c to use G_wait() instead of _cwait()? _cwait() is only defined as working with process IDs returned from the _spawn functions, which are no longer used.

Using G_wait() instead of _cwait() works for me in trunk with g.copy,g.remove and v.in.ogr. G_wait() is not available in 6.4, although in 6.4 the _spawn functions have been eliminated as well. Has r42668 been an incomplete backport to 6.4? G_wait() has been introduced in trunk with r40648, i.e. before the backport to 6.4. Do the small differences in lib/gis/spawn.c between trunk and 6.4 really make sense? From your comment and my tests I understand that if the _spawn functions are eliminated, _cwait must be eliminated (replaced with G_wait()) as well.

Markus M

comment:43 in reply to:  42 Changed 8 years ago by mmetz

Replying to mmetz:

Replying to glynn:

Can you try modifying lib/db/dbmi_client/shutdown.c to use G_wait() instead of _cwait()? _cwait() is only defined as working with process IDs returned from the _spawn functions, which are no longer used.

Using G_wait() instead of _cwait() works for me in trunk with g.copy,g.remove and v.in.ogr. G_wait() is not available in 6.4, although in 6.4 the _spawn functions have been eliminated as well. Has r42668 been an incomplete backport to 6.4? G_wait() has been introduced in trunk with r40648, i.e. before the backport to 6.4.

Oops, I mean mostly backported to 6.4 in r40644, bits and pieces of further changes in trunk backported to 6.4 in r40650, r40718, r42668. Is it safe to completely backport spawn.c from trunk to 6.x?

comment:44 in reply to:  42 ; Changed 8 years ago by glynn

Replying to mmetz:

Has r42668 been an incomplete backport to 6.4? G_wait() has been introduced in trunk with r40648, i.e. before the backport to 6.4.

40648 changed a lot of other stuff. Specifically, it replaced the existing G_popen() function (which was just a wrapper around popen()) with a new function based around G_spawn_ex(), and changed everything which was using the previous G_popen() function accordingly.

It was at this point that the need for G_wait() was discovered, so it was added as part of the same changeset (r40648).

6.4 still uses the old G_popen() function and 6.5 uses popen() directly, so most of r40648 cannot be back-ported. But the changes to lib/gis/spawn.c can and should be.

Do the small differences in lib/gis/spawn.c between trunk and 6.4 really make sense?

No; that file should be sync'd from trunk to 6.x.

comment:45 in reply to:  44 ; Changed 8 years ago by mmetz

Replying to glynn:

Replying to mmetz:

Do the small differences in lib/gis/spawn.c between trunk and 6.4 really make sense?

No; that file should be sync'd from trunk to 6.x.

Done in r47965 and r47968 for 6.5 and 6.4, respectively.

db_shutdown_driver() fixed in r47966 and r47969 for 6.5 and 6.4, respectively.

The call to Vect_delete() by g.remove, g.mremove, v.in.ogr or any other module allowed to overwrite an existing vector map works for me now in Windows. Please confirm.

Markus M

comment:46 in reply to:  45 ; Changed 8 years ago by lutra

Replying to mmetz:

Please confirm.

Markus M

it seems to work, but I would like also to confirm on OSGeo4W, when the GRASS 6.4svn will be available...

comment:47 Changed 8 years ago by arencambre

#1438 duplicates this.

comment:48 in reply to:  46 Changed 8 years ago by mmetz

Replying to lutra:

Replying to mmetz:

Please confirm.

Markus M

it seems to work, but I would like also to confirm on OSGeo4W, when the GRASS 6.4svn will be available...

Daily snapshots of GRASS 6.4svn built with OSGeo4W are available here:

http://wingrass.fsv.cvut.cz/grass64/

Please note that GRASS 6.4svn will only become available directly through the OSGeo4W installer if this and other bugs are confirmed to be fixed.

Markus M

comment:49 Changed 8 years ago by lutra

Giuseppe Sucameli (Faunalia) made to compile the necessary packages (qgis-trunk and GRASS 6.4.2svn, latest revisions) for osgeo4w and so I made the necessary tests (mostly using the QGIS/GRASS interface)

The issue described in this ticket seems "fixed," but with some limitations.

It is possible now to remove one vector at the same time using the proper button in the QGIS/GRASS plugin.

Selecting multiple vectors (in the QGIS/GRASS mapset browser) and removing them (with the remove button) leads to corruption of the vectors, the mapset become unusable and it is needed to delete manually the vector folders/files (not before closing QGIS).

This problem does not affect g.remove used in the GRASS shell (launched via the QGIS/GRASS plugin) nor the g.remove GRASS GUI (launched via the QGIS/GRASS shell), so it seems that is a QGIS only problem.

Another issue is that if a GRASS vector is rendered in the QGIS canvas and you try to remove it (using the plugin button, or g.remove from the CLI or the GRASS GUI) then it becomes corrupted: the command removes the dbf file, but cannot make to delete the files "hist" and "topo" in the folder named after the vector. This because the files are in use by QGIS, and it is not possible to remove them even manually, if not closing QGIS.

On the QGIS/GRASS plugin side we are thinking to not allow remove any vector that is being rendered in the canvas, but the problem would still affect the CLI and the g.remove GRASS native interface.

Not sure if the problem when removing multiple vectors is related or not.

http://ubuntuone.com/2lRa1ReYqBIoP9daJXjaU9

GRASS 6.4.2svn

http://ubuntuone.com/78DkQJB5qmuOHogTC3aXIf

QGIS trunk compiled for GRASS svn

http://ubuntuone.com/16JW6U3PXY19n22L6NZ6MB

launcher for the above QGIS binary

comment:50 in reply to:  49 ; Changed 8 years ago by lutra

Selecting multiple vectors (in the QGIS/GRASS mapset browser) and removing them (with the remove button) leads to corruption of the vectors, the mapset become unusable and it is needed to delete manually the vector folders/files (not before closing QGIS).

after all it seems if that no one of the selected vectors is being rendered in the QGIS canvas, then is possible to remove them without any issue.

comment:51 in reply to:  50 ; Changed 8 years ago by mmetz

Resolution: fixed
Status: newclosed

Replying to lutra:

Selecting multiple vectors (in the QGIS/GRASS mapset browser) and removing them (with the remove button) leads to corruption of the vectors, the mapset become unusable and it is needed to delete manually the vector folders/files (not before closing QGIS).

after all it seems if that no one of the selected vectors is being rendered in the QGIS canvas, then is possible to remove them without any issue.

A file can not be removed as long as it is kept open by some application. This is a universal feature I guess. At least it applies to Linux and MS Windows.

I see two possibilities to fix this QGIS bug:

  1. QGIS must close all corresponding files once it has finished rendering a GRASS vector or raster map. It can still be displayed in the QGIS canvas after rendering but the files must be closed.
  1. The QGIS-GRASS plugin handling of g.remove and g.mremove (and pretty much all modules producing an output raster or vector map) must make sure that the maps to be deleted (or overwritten) are not kept open by QGIS.

Closing this ticket because it has been confirmed to work with GRASS and remains a problem with the QGIS-GRASS plugin.

comment:52 Changed 8 years ago by arencambre

I've un-marked #1438 as duplicate. It appears this issue may be unrelated.

comment:53 in reply to:  51 Changed 8 years ago by hamish

Replying to mmetz:

A file can not be removed as long as it is kept open by some application. This is a universal feature I guess. At least it applies to Linux and MS Windows.

AFAIU it's rather different on Linux and MS Windows. On linux you can delete an open file, and for all intents and purposes that works and it is deleted, but the actual file isn't really gone on disk until the last program that has it open has closed it. On Windows however if another process has a file open you get a nasty error message.

It's sort of like Linux is asking to do a "lazy" umount, which disconnects for new requests but leaves the line open in the background (usually waiting for a hung NFS mount to revive), while the analogy for Windows would be a normal umount, where it complains and fails if anything is still using it.

I assume that file deletion on all/most UNIX file systems follow the same manner as Linux in this regard.

Hamish

Note: See TracTickets for help on using tickets.