@@ -36,14 +36,66 @@ public static RuntimeScalar chdir(RuntimeScalar runtimeScalar) {
3636        //            directory handle as the argument. On systems that don't support 
3737        //            fchdir(2), passing handles raises an exception. 
3838
39-         String  dirName  = runtimeScalar .toString ();
39+         String  dirName ;
40+         
41+         // Check if argument is a filehandle or dirhandle 
42+         if  (runtimeScalar .value  instanceof  RuntimeIO  || runtimeScalar .value  instanceof  RuntimeGlob ) {
43+             // Try to get RuntimeIO from the scalar 
44+             RuntimeIO  io  = RuntimeIO .getRuntimeIO (runtimeScalar );
45+             if  (io  != null ) {
46+                 // This is a filehandle or dirhandle - fchdir is not supported 
47+                 throw  new  PerlCompilerException ("The fchdir function is unimplemented" );
48+             }
49+         }
50+         
51+         // Handle chdir() with no arguments - check environment variables 
52+         if  (!runtimeScalar .defined ().getBoolean ()) {
53+             // Try HOME, then LOGDIR, then SYS$LOGIN (for VMS only) 
54+             RuntimeHash  envHash  = GlobalVariable .getGlobalHash ("main::ENV" );
55+             RuntimeScalar  homeDir  = envHash .get ("HOME" );
56+             if  (homeDir  != null  && homeDir .defined ().getBoolean () && !homeDir .toString ().isEmpty ()) {
57+                 dirName  = homeDir .toString ();
58+             } else  {
59+                 RuntimeScalar  logDir  = envHash .get ("LOGDIR" );
60+                 if  (logDir  != null  && logDir .defined ().getBoolean () && !logDir .toString ().isEmpty ()) {
61+                     dirName  = logDir .toString ();
62+                 } else  {
63+                     // Check SYS$LOGIN only on VMS 
64+                     String  osName  = GlobalVariable .getGlobalVariable ("main::^O" ).toString ();
65+                     if  ("VMS" .equalsIgnoreCase (osName )) {
66+                         RuntimeScalar  sysLogin  = envHash .get ("SYS$LOGIN" );
67+                         if  (sysLogin  != null  && sysLogin .defined ().getBoolean () && !sysLogin .toString ().isEmpty ()) {
68+                             dirName  = sysLogin .toString ();
69+                         } else  {
70+                             // No environment variable set - fail with EINVAL 
71+                             getGlobalVariable ("main::!" ).set (22 );  // EINVAL 
72+                             return  scalarFalse ;
73+                         }
74+                     } else  {
75+                         // Not VMS and no HOME/LOGDIR - fail with EINVAL 
76+                         getGlobalVariable ("main::!" ).set (22 );  // EINVAL 
77+                         return  scalarFalse ;
78+                     }
79+                 }
80+             }
81+         } else  {
82+             dirName  = runtimeScalar .toString ();
83+         }
84+         
85+         // Check for empty string - should fail with ENOENT 
86+         if  (dirName .isEmpty ()) {
87+             getGlobalVariable ("main::!" ).set (2 );  // ENOENT 
88+             return  scalarFalse ;
89+         }
90+         
4091        File  absoluteDir  = RuntimeIO .resolveFile (dirName );
4192
4293        if  (absoluteDir .exists () && absoluteDir .isDirectory ()) {
4394            System .setProperty ("user.dir" , absoluteDir .getAbsolutePath ());
4495            return  scalarTrue ;
4596        } else  {
46-             getGlobalVariable ("main::!" ).set ("chdir failed: No such directory '"  + dirName  + "'" );
97+             // Set errno to ENOENT (No such file or directory) 
98+             getGlobalVariable ("main::!" ).set (2 );  // ENOENT 
4799            return  scalarFalse ;
48100        }
49101    }
0 commit comments