builder: add a verror, when the output folder is not existing and writable (#5966)
							parent
							
								
									3e4df7f140
								
							
						
					
					
						commit
						8dede3b535
					
				
							
								
								
									
										19
									
								
								vlib/os/os.v
								
								
								
								
							
							
						
						
									
										19
									
								
								vlib/os/os.v
								
								
								
								
							|  | @ -511,23 +511,6 @@ pub fn is_executable(path string) bool { | |||
|   return C.access(charptr(path.str), x_ok) != -1 | ||||
| } | ||||
| 
 | ||||
| // `is_writable_folder` - `folder` exists and is writable to the process
 | ||||
| pub fn is_writable_folder(folder string) ?bool { | ||||
| 	if !os.exists(folder) { | ||||
| 		return error('`$folder` does not exist') | ||||
| 	} | ||||
| 	if !os.is_dir(folder) { | ||||
| 		return error('`folder` is not a folder') | ||||
| 	} | ||||
| 	tmp_perm_check := os.join_path(folder, 'tmp_perm_check') | ||||
| 	mut f := os.open_file(tmp_perm_check, 'w+', 0o700) or { | ||||
| 		return error('cannot write to folder `$folder`: $err') | ||||
| 	} | ||||
| 	f.close() | ||||
| 	os.rm(tmp_perm_check) | ||||
| 	return true | ||||
| } | ||||
| 
 | ||||
| // `is_writable` returns `true` if `path` is writable.
 | ||||
| pub fn is_writable(path string) bool { | ||||
|   $if windows { | ||||
|  | @ -638,7 +621,7 @@ pub fn dir(path string) string { | |||
| 
 | ||||
| pub fn base_dir(path string) string { | ||||
| 	posx := path.last_index(path_separator) or { | ||||
| 		return path | ||||
| 		return path.clone() | ||||
| 	} | ||||
| 	// NB: *without* terminating /
 | ||||
| 	return path[..posx] | ||||
|  |  | |||
|  | @ -190,3 +190,24 @@ pub fn (mut f File) close() { | |||
| pub fn debugger_present() bool { | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| fn C.mkstemp(stemplate byteptr) int | ||||
| // `is_writable_folder` - `folder` exists and is writable to the process
 | ||||
| pub fn is_writable_folder(folder string) ?bool { | ||||
| 	if !os.exists(folder) { | ||||
| 		return error('`$folder` does not exist') | ||||
| 	} | ||||
| 	if !os.is_dir(folder) { | ||||
| 		return error('`folder` is not a folder') | ||||
| 	} | ||||
| 	tmp_perm_check := os.join_path(folder, 'XXXXXX') | ||||
| 	unsafe { | ||||
| 		x := C.mkstemp(tmp_perm_check.str) | ||||
| 		if -1 == x { | ||||
| 			return error('folder `$folder` is not writable') | ||||
| 		} | ||||
| 		C.close(x) | ||||
| 	} | ||||
| 	os.rm(tmp_perm_check) | ||||
| 	return true | ||||
| } | ||||
|  |  | |||
|  | @ -366,3 +366,21 @@ pub fn uname() Uname { | |||
| 		machine: unknown | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // `is_writable_folder` - `folder` exists and is writable to the process
 | ||||
| pub fn is_writable_folder(folder string) ?bool { | ||||
| 	if !os.exists(folder) { | ||||
| 		return error('`$folder` does not exist') | ||||
| 	} | ||||
| 	if !os.is_dir(folder) { | ||||
| 		return error('`folder` is not a folder') | ||||
| 	} | ||||
| 	tmp_perm_check := os.join_path(folder, 'tmp_perm_check') | ||||
| 	mut f := os.open_file(tmp_perm_check, 'w+', 0o700) or { | ||||
| 		return error('cannot write to folder $folder: $err') | ||||
| 	} | ||||
| 	f.close() | ||||
| 	os.rm(tmp_perm_check) | ||||
| 	return true | ||||
| } | ||||
|  |  | |||
|  | @ -27,6 +27,18 @@ fn get_vtmp_filename(base_file_name, postfix string) string { | |||
| } | ||||
| 
 | ||||
| pub fn compile(command string, pref &pref.Preferences) { | ||||
| 	odir := os.base_dir(pref.out_name) | ||||
| 	// When pref.out_name is just the name of an executable, i.e. `./v -o executable main.v`
 | ||||
| 	// without a folder component, just use the current folder instead:
 | ||||
| 	mut output_folder := odir | ||||
| 	if odir.len == pref.out_name.len { | ||||
| 		output_folder = os.getwd() | ||||
| 	}         | ||||
| 	os.is_writable_folder(output_folder) or {  | ||||
| 		// An early error here, is better than an unclear C error later:
 | ||||
| 		verror(err) | ||||
| 		exit(1) | ||||
| 	} | ||||
| 	// Construct the V object from command line arguments
 | ||||
| 	mut b := new_builder(pref) | ||||
| 	if pref.is_verbose { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue