2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-04 13:19:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								 *  Copyright  ( c )  2018 - 2021 ,  Andreas  Kling  < andreas @ ladybird . org > 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								 *  Copyright  ( c )  2021 ,  sin - ack  < sin - ack @ protonmail . com > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  SPDX - License - Identifier :  BSD - 2 - Clause 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-09 03:02:46 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <LibCore/File.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-13 21:21:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <LibCore/System.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								# include  <fcntl.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <unistd.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-09 03:02:46 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								namespace  Core  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 20:18:07 +03:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								ErrorOr < NonnullOwnPtr < File > >  File : : open ( StringView  filename ,  OpenMode  mode ,  mode_t  permissions ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-29 22:31:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    auto  file  =  TRY ( adopt_nonnull_own_or_enomem ( new  ( nothrow )  File ( mode ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    TRY ( file - > open_path ( filename ,  permissions ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    return  file ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-12 11:31:34 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								ErrorOr < NonnullOwnPtr < File > >  File : : adopt_fd ( int  fd ,  OpenMode  mode ,  ShouldCloseFileDescriptor  should_close_file_descriptor ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( fd  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  Error : : from_errno ( EBADF ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! has_any_flag ( mode ,  OpenMode : : ReadWrite ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-09 03:02:46 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        dbgln ( " Core::File::adopt_fd: Attempting to adopt a file with neither Read nor Write specified in mode " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        return  Error : : from_errno ( EINVAL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-12 11:31:34 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    auto  file  =  TRY ( adopt_nonnull_own_or_enomem ( new  ( nothrow )  File ( mode ,  should_close_file_descriptor ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-29 22:31:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    file - > m_fd  =  fd ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    return  file ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-13 23:52:57 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								ErrorOr < NonnullOwnPtr < File > >  File : : standard_input ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  File : : adopt_fd ( STDIN_FILENO ,  OpenMode : : Read ,  ShouldCloseFileDescriptor : : No ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								ErrorOr < NonnullOwnPtr < File > >  File : : standard_output ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  File : : adopt_fd ( STDOUT_FILENO ,  OpenMode : : Write ,  ShouldCloseFileDescriptor : : No ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								ErrorOr < NonnullOwnPtr < File > >  File : : standard_error ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  File : : adopt_fd ( STDERR_FILENO ,  OpenMode : : Write ,  ShouldCloseFileDescriptor : : No ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-22 13:24:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								ErrorOr < NonnullOwnPtr < File > >  File : : open_file_or_standard_stream ( StringView  filename ,  OpenMode  mode ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! filename . is_empty ( )  & &  filename  ! =  " - " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  File : : open ( filename ,  mode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    switch  ( mode )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    case  OpenMode : : Read : 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-13 23:52:57 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  standard_input ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-22 13:24:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    case  OpenMode : : Write : 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-13 23:52:57 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  standard_output ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-22 13:24:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-10 18:17:31 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  File : : open_mode_to_options ( OpenMode  mode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  flags  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-10 18:17:31 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( has_flag ( mode ,  OpenMode : : ReadWrite ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        flags  | =  O_RDWR  |  O_CREAT ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-10 18:17:31 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    }  else  if  ( has_flag ( mode ,  OpenMode : : Read ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        flags  | =  O_RDONLY ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-10 18:17:31 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    }  else  if  ( has_flag ( mode ,  OpenMode : : Write ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        flags  | =  O_WRONLY  |  O_CREAT ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-10 18:17:31 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        bool  should_truncate  =  ! has_any_flag ( mode ,  OpenMode : : Append  |  OpenMode : : MustBeNew ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        if  ( should_truncate ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            flags  | =  O_TRUNC ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-10 18:17:31 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( has_flag ( mode ,  OpenMode : : Append ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        flags  | =  O_APPEND ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-10 18:17:31 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( has_flag ( mode ,  OpenMode : : Truncate ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        flags  | =  O_TRUNC ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-10 18:17:31 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( has_flag ( mode ,  OpenMode : : MustBeNew ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        flags  | =  O_EXCL ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-10 18:17:31 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ! has_flag ( mode ,  OpenMode : : KeepOnExec ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        flags  | =  O_CLOEXEC ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-13 18:13:31 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( has_flag ( mode ,  OpenMode : : Nonblocking ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        flags  | =  O_NONBLOCK ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 23:30:32 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // Some open modes, like `ReadWrite` imply the ability to create the file if it doesn't exist.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // Certain applications may not want this privledge, and for compability reasons, this is
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // the easiest way to add this option.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( has_flag ( mode ,  OpenMode : : DontCreate ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        flags  & =  ~ O_CREAT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-10 18:17:31 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								ErrorOr < void >  File : : open_path ( StringView  filename ,  mode_t  permissions ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    VERIFY ( m_fd  = =  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  flags  =  open_mode_to_options ( m_mode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-08 23:12:31 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    m_fd  =  TRY ( System : : open ( filename ,  flags ,  permissions ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-24 22:38:01 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								ErrorOr < Bytes >  File : : read_some ( Bytes  buffer ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! has_flag ( m_mode ,  OpenMode : : Read ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // NOTE: POSIX says that if the fd is not open for reading, the call
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        //       will return EBADF. Since we already know whether we can or
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        //       can't read the file, let's avoid a syscall.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-29 23:13:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  Error : : from_errno ( EBADF ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 13:24:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ssize_t  nread  =  TRY ( System : : read ( m_fd ,  buffer ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m_last_read_was_eof  =  nread  = =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-06 13:41:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    m_file_offset  + =  nread ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-15 13:33:02 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  buffer . trim ( nread ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-11 17:49:00 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								ErrorOr < ByteBuffer >  File : : read_until_eof ( size_t  block_size ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 12:57:31 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // Note: This is used as a heuristic, it's not valid for devices or virtual files.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  const  potential_file_size  =  TRY ( System : : fstat ( m_fd ) ) . st_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-11 17:49:00 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  read_until_eof_impl ( block_size ,  potential_file_size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 12:57:31 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-24 22:38:01 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								ErrorOr < size_t >  File : : write_some ( ReadonlyBytes  buffer ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! has_flag ( m_mode ,  OpenMode : : Write ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // NOTE: Same deal as Read.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-29 23:13:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  Error : : from_errno ( EBADF ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-06 13:41:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    auto  nwritten  =  TRY ( System : : write ( m_fd ,  buffer ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m_file_offset  + =  nwritten ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  nwritten ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								bool  File : : is_eof ( )  const  {  return  m_last_read_was_eof ;  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								bool  File : : is_open ( )  const  {  return  m_fd  > =  0 ;  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  File : : close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! is_open ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // NOTE: The closing of the file can be interrupted by a signal, in which
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // case EINTR will be returned by the close syscall. So let's try closing
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // the file until we aren't interrupted by rude signals. :^)
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 13:24:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ErrorOr < void >  result ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    do  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 13:24:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        result  =  System : : close ( m_fd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  while  ( result . is_error ( )  & &  result . error ( ) . code ( )  = =  EINTR ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 13:24:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    VERIFY ( ! result . is_error ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    m_fd  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-17 14:52:46 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								ErrorOr < size_t >  File : : seek ( i64  offset ,  SeekMode  mode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  syscall_mode ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    switch  ( mode )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    case  SeekMode : : SetPosition : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        syscall_mode  =  SEEK_SET ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    case  SeekMode : : FromCurrentPosition : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        syscall_mode  =  SEEK_CUR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    case  SeekMode : : FromEndPosition : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        syscall_mode  =  SEEK_END ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-17 14:52:46 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    size_t  seek_result  =  TRY ( System : : lseek ( m_fd ,  offset ,  syscall_mode ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-06 13:41:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    m_file_offset  =  seek_result ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    m_last_read_was_eof  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 13:24:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  seek_result ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-06 13:41:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								ErrorOr < size_t >  File : : tell ( )  const 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  m_file_offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-29 13:49:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								ErrorOr < void >  File : : truncate ( size_t  length ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-03 19:21:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-29 13:49:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( length  >  static_cast < size_t > ( NumericLimits < off_t > : : max ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  Error : : from_string_literal ( " Length is larger than the maximum supported length " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-06 13:41:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    m_file_offset  =  min ( length ,  m_file_offset ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-03 19:21:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  System : : ftruncate ( m_fd ,  length ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-21 22:24:58 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								ErrorOr < void >  File : : set_blocking ( bool  enabled ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // NOTE: This works fine on Serenity, but some systems out there don't support changing the blocking state of certain POSIX objects (message queues, pipes, etc) after their creation.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // Therefore, this method shouldn't be used in Lagom.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // https://github.com/SerenityOS/serenity/pull/18965#discussion_r1207951840
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  value  =  enabled  ?  0  :  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  System : : ioctl ( fd ( ) ,  FIONBIO ,  & value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 21:30:13 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								}