@@ -73,6 +73,7 @@ const {
7373 codes : {
7474 ERR_ACCESS_DENIED ,
7575 ERR_FS_FILE_TOO_LARGE ,
76+ ERR_INVALID_ARG_TYPE ,
7677 ERR_INVALID_ARG_VALUE ,
7778 } ,
7879} = require ( 'internal/errors' ) ;
@@ -1620,22 +1621,57 @@ function lstat(path, options = { bigint: false }, callback) {
16201621/**
16211622 * Asynchronously gets the stats of a file.
16221623 * @param {string | Buffer | URL } path
1623- * @param {{ bigint?: boolean; } } [options]
1624+ * @param {{ bigint?: boolean, signal?: AbortSignal } } [options]
16241625 * @param {(
16251626 * err?: Error,
16261627 * stats?: Stats
16271628 * ) => any} callback
16281629 * @returns {void }
16291630 */
1630- function stat ( path , options = { bigint : false } , callback ) {
1631+ function stat ( path , options = { __proto__ : null , bigint : false , signal : undefined } , callback ) {
16311632 if ( typeof options === 'function' ) {
16321633 callback = options ;
16331634 options = kEmptyObject ;
1635+ } else if ( options === null || typeof options !== 'object' ) {
1636+ options = kEmptyObject ;
1637+ } else {
1638+ options = getOptions ( options , { __proto__ : null , bigint : false , signal : undefined } ) ;
1639+ }
1640+
1641+ if ( typeof callback !== 'function' ) {
1642+ throw new ERR_INVALID_ARG_TYPE ( 'callback' , 'Function' , callback ) ;
16341643 }
1635- callback = makeStatsCallback ( callback ) ;
16361644
1645+ const originalCallback = callback ;
16371646 const req = new FSReqCallback ( options . bigint ) ;
1638- req . oncomplete = callback ;
1647+
1648+ if ( options . signal ?. aborted ) {
1649+ const abortErr = new AbortError ( 'The operation was aborted' , { __proto__ : null , cause : options . signal . reason } ) ;
1650+ return process . nextTick ( ( ) => originalCallback ( abortErr ) ) ;
1651+ }
1652+
1653+ let aborted = false ;
1654+ const onAbort = ( ) => {
1655+ aborted = true ;
1656+ originalCallback ( new AbortError ( undefined , { __proto__ : null , cause : options . signal . reason } ) ) ;
1657+ } ;
1658+
1659+ if ( options . signal ) {
1660+ options . signal . addEventListener ( 'abort' , onAbort , { __proto__ : null , once : true } ) ;
1661+ }
1662+
1663+ req . oncomplete = ( err , stats ) => {
1664+ if ( options . signal ) {
1665+ options . signal . removeEventListener ( 'abort' , onAbort ) ;
1666+ }
1667+
1668+ if ( aborted ) return ;
1669+
1670+ const wrappedCallback = makeStatsCallback ( originalCallback ) ;
1671+
1672+ wrappedCallback ( err , stats ) ;
1673+ } ;
1674+
16391675 binding . stat ( getValidatedPath ( path ) , options . bigint , req ) ;
16401676}
16411677
0 commit comments