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 |   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.
 | // `is_writable` returns `true` if `path` is writable.
 | ||||||
| pub fn is_writable(path string) bool { | pub fn is_writable(path string) bool { | ||||||
|   $if windows { |   $if windows { | ||||||
|  | @ -638,7 +621,7 @@ pub fn dir(path string) string { | ||||||
| 
 | 
 | ||||||
| pub fn base_dir(path string) string { | pub fn base_dir(path string) string { | ||||||
| 	posx := path.last_index(path_separator) or { | 	posx := path.last_index(path_separator) or { | ||||||
| 		return path | 		return path.clone() | ||||||
| 	} | 	} | ||||||
| 	// NB: *without* terminating /
 | 	// NB: *without* terminating /
 | ||||||
| 	return path[..posx] | 	return path[..posx] | ||||||
|  |  | ||||||
|  | @ -190,3 +190,24 @@ pub fn (mut f File) close() { | ||||||
| pub fn debugger_present() bool { | pub fn debugger_present() bool { | ||||||
| 	return false | 	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 | 		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) { | 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
 | 	// Construct the V object from command line arguments
 | ||||||
| 	mut b := new_builder(pref) | 	mut b := new_builder(pref) | ||||||
| 	if pref.is_verbose { | 	if pref.is_verbose { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue