@@ -262,7 +262,8 @@ export class FileService implements IFileService {
262262 if ( resource . scheme !== 'file' || ! resource . fsPath ) {
263263 return TPromise . wrapError < IStreamContent > ( new FileOperationError (
264264 nls . localize ( 'fileInvalidPath' , "Invalid file resource ({0})" , resource . toString ( true ) ) ,
265- FileOperationResult . FILE_INVALID_PATH
265+ FileOperationResult . FILE_INVALID_PATH ,
266+ options
266267 ) ) ;
267268 }
268269
@@ -298,23 +299,26 @@ export class FileService implements IFileService {
298299 if ( stat . isDirectory ) {
299300 return onStatError ( new FileOperationError (
300301 nls . localize ( 'fileIsDirectoryError' , "File is directory" ) ,
301- FileOperationResult . FILE_IS_DIRECTORY
302+ FileOperationResult . FILE_IS_DIRECTORY ,
303+ options
302304 ) ) ;
303305 }
304306
305307 // Return early if file not modified since
306308 if ( options && options . etag && options . etag === stat . etag ) {
307309 return onStatError ( new FileOperationError (
308310 nls . localize ( 'fileNotModifiedError' , "File not modified since" ) ,
309- FileOperationResult . FILE_NOT_MODIFIED_SINCE
311+ FileOperationResult . FILE_NOT_MODIFIED_SINCE ,
312+ options
310313 ) ) ;
311314 }
312315
313316 // Return early if file is too large to load
314317 if ( typeof stat . size === 'number' && stat . size > MAX_FILE_SIZE ) {
315318 return onStatError ( new FileOperationError (
316319 nls . localize ( 'fileTooLargeError' , "File too large to open" ) ,
317- FileOperationResult . FILE_TOO_LARGE
320+ FileOperationResult . FILE_TOO_LARGE ,
321+ options
318322 ) ) ;
319323 }
320324
@@ -325,7 +329,8 @@ export class FileService implements IFileService {
325329 if ( err . code === 'ENOENT' ) {
326330 return onStatError ( new FileOperationError (
327331 nls . localize ( 'fileNotFoundError' , "File not found ({0})" , resource . toString ( true ) ) ,
328- FileOperationResult . FILE_NOT_FOUND
332+ FileOperationResult . FILE_NOT_FOUND ,
333+ options
329334 ) ) ;
330335 }
331336
@@ -374,7 +379,8 @@ export class FileService implements IFileService {
374379 // Wrap file not found errors
375380 err = new FileOperationError (
376381 nls . localize ( 'fileNotFoundError' , "File not found ({0})" , resource . toString ( true ) ) ,
377- FileOperationResult . FILE_NOT_FOUND
382+ FileOperationResult . FILE_NOT_FOUND ,
383+ options
378384 ) ;
379385 }
380386
@@ -391,7 +397,8 @@ export class FileService implements IFileService {
391397 // Wrap EISDIR errors (fs.open on a directory works, but you cannot read from it)
392398 err = new FileOperationError (
393399 nls . localize ( 'fileIsDirectoryError' , "File is directory" ) ,
394- FileOperationResult . FILE_IS_DIRECTORY
400+ FileOperationResult . FILE_IS_DIRECTORY ,
401+ options
395402 ) ;
396403 }
397404 if ( decoder ) {
@@ -442,7 +449,8 @@ export class FileService implements IFileService {
442449 // stop when reading too much
443450 finish ( new FileOperationError (
444451 nls . localize ( 'fileTooLargeError' , "File too large to open" ) ,
445- FileOperationResult . FILE_TOO_LARGE
452+ FileOperationResult . FILE_TOO_LARGE ,
453+ options
446454 ) ) ;
447455 } else if ( err ) {
448456 // some error happened
@@ -464,7 +472,8 @@ export class FileService implements IFileService {
464472 // Return error early if client only accepts text and this is not text
465473 finish ( new FileOperationError (
466474 nls . localize ( 'fileBinaryError' , "File seems to be binary and cannot be opened as text" ) ,
467- FileOperationResult . FILE_IS_BINARY
475+ FileOperationResult . FILE_IS_BINARY ,
476+ options
468477 ) ) ;
469478
470479 } else {
@@ -553,7 +562,8 @@ export class FileService implements IFileService {
553562 if ( error . code === 'EACCES' || error . code === 'EPERM' ) {
554563 return TPromise . wrapError ( new FileOperationError (
555564 nls . localize ( 'filePermission' , "Permission denied writing to file ({0})" , resource . toString ( true ) ) ,
556- FileOperationResult . FILE_PERMISSION_DENIED
565+ FileOperationResult . FILE_PERMISSION_DENIED ,
566+ options
557567 ) ) ;
558568 }
559569
@@ -600,7 +610,14 @@ export class FileService implements IFileService {
600610 return ( import ( 'sudo-prompt' ) ) . then ( sudoPrompt => {
601611 return new TPromise < void > ( ( c , e ) => {
602612 const promptOptions = { name : this . options . elevationSupport . promptTitle . replace ( '-' , '' ) , icns : this . options . elevationSupport . promptIcnsPath } ;
603- sudoPrompt . exec ( `"${ this . options . elevationSupport . cliPath } " --write-elevated-helper "${ tmpPath } " "${ absolutePath } "` , promptOptions , ( error : string , stdout : string , stderr : string ) => {
613+
614+ const sudoCommand : string [ ] = [ `"${ this . options . elevationSupport . cliPath } "` ] ;
615+ if ( options . overwriteReadonly ) {
616+ sudoCommand . push ( '--sudo-chmod' ) ;
617+ }
618+ sudoCommand . push ( '--sudo-write' , `"${ tmpPath } "` , `"${ absolutePath } "` ) ;
619+
620+ sudoPrompt . exec ( sudoCommand . join ( ' ' ) , promptOptions , ( error : string , stdout : string , stderr : string ) => {
604621 if ( error || stderr ) {
605622 e ( error || stderr ) ;
606623 } else {
@@ -622,7 +639,8 @@ export class FileService implements IFileService {
622639 if ( ! ( error instanceof FileOperationError ) ) {
623640 error = new FileOperationError (
624641 nls . localize ( 'filePermission' , "Permission denied writing to file ({0})" , resource . toString ( true ) ) ,
625- FileOperationResult . FILE_PERMISSION_DENIED
642+ FileOperationResult . FILE_PERMISSION_DENIED ,
643+ options
626644 ) ;
627645 }
628646
@@ -645,7 +663,8 @@ export class FileService implements IFileService {
645663 if ( exists && ! options . overwrite ) {
646664 return TPromise . wrapError < IFileStat > ( new FileOperationError (
647665 nls . localize ( 'fileExists' , "File to create already exists ({0})" , resource . toString ( true ) ) ,
648- FileOperationResult . FILE_MODIFIED_SINCE
666+ FileOperationResult . FILE_MODIFIED_SINCE ,
667+ options
649668 ) ) ;
650669 }
651670
@@ -914,14 +933,14 @@ export class FileService implements IFileService {
914933
915934 // Find out if content length has changed
916935 if ( options . etag !== etag ( stat . size , options . mtime ) ) {
917- return TPromise . wrapError < boolean > ( new FileOperationError ( nls . localize ( 'fileModifiedError' , "File Modified Since" ) , FileOperationResult . FILE_MODIFIED_SINCE ) ) ;
936+ return TPromise . wrapError < boolean > ( new FileOperationError ( nls . localize ( 'fileModifiedError' , "File Modified Since" ) , FileOperationResult . FILE_MODIFIED_SINCE , options ) ) ;
918937 }
919938 }
920939
921940 // Throw if file is readonly and we are not instructed to overwrite
922941 if ( ! ( stat . mode & 128 ) /* readonly */ ) {
923942 if ( ! options . overwriteReadonly ) {
924- return this . readOnlyError < boolean > ( ) ;
943+ return this . readOnlyError < boolean > ( options ) ;
925944 }
926945
927946 // Try to change mode to writeable
@@ -932,7 +951,7 @@ export class FileService implements IFileService {
932951 // Make sure to check the mode again, it could have failed
933952 return pfs . stat ( absolutePath ) . then ( stat => {
934953 if ( ! ( stat . mode & 128 ) /* readonly */ ) {
935- return this . readOnlyError < boolean > ( ) ;
954+ return this . readOnlyError < boolean > ( options ) ;
936955 }
937956
938957 return exists ;
@@ -948,10 +967,11 @@ export class FileService implements IFileService {
948967 } ) ;
949968 }
950969
951- private readOnlyError < T > ( ) : TPromise < T > {
970+ private readOnlyError < T > ( options : IUpdateContentOptions ) : TPromise < T > {
952971 return TPromise . wrapError < T > ( new FileOperationError (
953972 nls . localize ( 'fileReadOnlyError' , "File is Read Only" ) ,
954- FileOperationResult . FILE_READ_ONLY
973+ FileOperationResult . FILE_READ_ONLY ,
974+ options
955975 ) ) ;
956976 }
957977
0 commit comments