Index: trunk/LMDZ.COMMON/libf/misc/job_mod.F90
===================================================================
--- trunk/LMDZ.COMMON/libf/misc/job_mod.F90	(revision 4139)
+++ trunk/LMDZ.COMMON/libf/misc/job_mod.F90	(revision 4139)
@@ -0,0 +1,169 @@
+MODULE job_mod
+
+!-----------------------------------------------------------------------
+! NAME
+!     job_mod
+!
+! DESCRIPTION
+!     Tools to retieve job information of the program.
+!
+! AUTHORS & DATE
+!     JB Clement, 10/06/2024
+!
+! NOTES
+!
+!-----------------------------------------------------------------------
+
+! DECLARATION
+! -----------
+implicit none
+
+! PARAMETERS
+! ----------
+real            :: timelimit = 86400. ! Time limit for the job: 86400 s = 24 h by default
+real, parameter :: antetime  = 3600.  ! Anticipation time to prevent reaching the job time limit: 3600 s = 1 h by default
+logical         :: timewall = .false. ! Flag to enable the program self-termination before timeout
+
+contains
+!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+!=======================================================================
+SUBROUTINE get_job_id(jobid)
+!-----------------------------------------------------------------------
+! NAME
+!     get_job_id
+!
+! DESCRIPTION
+!     Retrieves the ID for a given job ID via SLURM or PBS/TORQUE.
+!
+! AUTHORS & DATE
+!     JB Clement, 10/06/2024
+!
+! NOTES
+!
+!-----------------------------------------------------------------------
+
+! DECLARATION
+! -----------
+implicit none
+
+! ARGUMENTS
+! ---------
+character(256), intent(out) :: jobid
+
+! LOCAL VARIABLES
+! ---------------
+integer        :: sts
+character(256) :: tmp
+
+! CODE
+! ----
+! Try SLURM
+call get_environment_variable("SLURM_JOBID",tmp,status = sts)
+if (sts == 0 .and. len_trim(tmp) > 0) then
+    jobid = trim(adjustl(tmp))
+    return
+endif
+
+! Try PBS/TORQUE  
+call get_environment_variable("PBS_JOBID",tmp,status = sts)
+if (sts == 0 .and. len_trim(tmp) > 0) then
+    ! Extract only the part before the point in '12345.master.cluster' to get the numeric job ID
+    jobid = trim(adjustl(tmp(1:index(tmp,'.') - 1)))
+    return
+endif
+
+error stop 'Error: neither SLURM_JOB_ID nor PBS_JOBID found in environment!'
+
+END SUBROUTINE get_job_id
+!=======================================================================
+
+!=======================================================================
+SUBROUTINE get_job_timelimit(jobid)
+!-----------------------------------------------------------------------
+! NAME
+!     get_job_timelimit
+!
+! DESCRIPTION
+!     Retrieves the time limit (in seconds) for a given job ID via SLURM
+!     or PBS/TORQUE.
+!
+! AUTHORS & DATE
+!     JB Clement, 10/06/2024
+!
+! NOTES
+!
+!-----------------------------------------------------------------------
+
+! DECLARATION
+! -----------
+implicit none
+
+! ARGUMENTS
+! ---------
+character(*), intent(in) :: jobid
+
+! LOCAL VARIABLES
+! ---------------
+logical        :: num_str
+character(256) :: chtimelimit ! Time limit for the job outputted by the SLURM or PBS/TORQUE command
+integer        :: i, ierr, funit, cstat, days, hours, minutes, seconds
+character(1)   :: sep
+
+! CODE
+! ----
+! Check that the job ID is numeric
+num_str = .true.
+do i = 1,len_trim(jobid)
+    if (jobid(i:i) < '0' .or. jobid(i:i) > '9') then
+        num_str = .false.
+        exit
+    endif
+enddo
+if (.not. num_str) error stop "Error: job ID must be numeric!"
+
+! Try SLURM (squeue)
+call execute_command_line('squeue -j '//trim(adjustl(jobid))//' -h --Format TimeLimit > tmp_timelimit.txt',cmdstat = cstat)
+if (cstat /= 0) then
+    ! On failure, try PBS/TORQUE (qstat)
+    call execute_command_line('qstat -f '//trim(adjustl(jobid))//' | grep "Walltime" | awk ''{print $3}'' > tmp_timelimit.txt',cmdstat = cstat)
+    if (cstat > 0) then
+        error stop 'Error: command execution failed!'
+    else if (cstat < 0) then
+        error stop 'Error: command execution not supported (neither SLURM nor PBS/TORQUE is installed)!'
+    endif
+endif
+
+! Read the output
+open(newunit = funit,file = 'tmp_timelimit.txt',status = 'old',form = 'formatted',action = 'read',iostat = ierr)
+if (ierr /= 0) error stop 'Error: error opening file "tmp_timelimit.txt"!'
+read(funit,'(a)') chtimelimit
+close(funit)
+chtimelimit = trim(adjustl(chtimelimit))
+
+! Remove temporary file
+call execute_command_line('rm tmp_timelimit.txt',cmdstat = cstat)
+if (cstat > 0) then
+    error stop 'Error: command execution failed!'
+else if (cstat < 0) then
+    error stop 'Error: command execution not supported!'
+endif
+
+! Parse D-HH:MM:SS, HH:MM:SS or MM:SS
+if (index(chtimelimit,'-') > 0) then ! Format "D-HH:MM:SS"
+    read(chtimelimit,'(i1,a1,i2,a1,i2,a1,i2)') days, sep, hours, sep, minutes, sep, seconds
+    timelimit = real(days)*86400. + real(hours)*3600. + real(minutes)*60. + real(seconds)
+else if (index(chtimelimit,':') > 0 .and. len_trim(chtimelimit) > 5) then ! Format "HH:MM:SS"
+    read(chtimelimit,'(i2,a1,i2,a1,i2)') hours, sep, minutes, sep, seconds
+    timelimit = real(hours)*3600. + real(minutes)*60. + real(seconds)
+else ! Format "MM:SS"
+    read(chtimelimit,'(i2,a1,i2)') minutes, sep, seconds
+    timelimit = real(minutes)*60. + real(seconds)
+endif
+
+timewall = .true.
+
+END SUBROUTINE get_job_timelimit
+!=======================================================================
+
+END MODULE job_mod
Index: trunk/LMDZ.COMMON/libf/misc/parse_args_mod.F90
===================================================================
--- trunk/LMDZ.COMMON/libf/misc/parse_args_mod.F90	(revision 4138)
+++ trunk/LMDZ.COMMON/libf/misc/parse_args_mod.F90	(revision 4139)
@@ -14,5 +14,5 @@
 use pgrm_version_mod,  only: print_pgrm_version
 #endif
-use job,               only: get_job_id, get_job_timelimit
+use job_mod,           only: get_job_id, get_job_timelimit
 
 implicit none
