# <!-- rdoc-file=process.c -->
# The module contains several groups of functionality for handling OS processes:
#
# *   Low-level property introspection and management of the current process,
#     like Process.argv0, Process.pid;
# *   Low-level introspection of other processes, like Process.getpgid,
#     Process.getpriority;
# *   Management of the current process: Process.abort, Process.exit,
#     Process.daemon, etc. (for convenience, most of those are also available as
#     global functions and module functions of Kernel);
# *   Creation and management of child processes: Process.fork, Process.spawn,
#     and related methods;
# *   Management of low-level system clock: Process.times and
#     Process.clock_gettime, which could be important for proper benchmarking
#     and other elapsed time measurement tasks.
#
module Process
  # <!--
  #   rdoc-file=process.c
  #   - Process._fork   -> integer
  # -->
  # An internal API for fork. Do not call this method directly. Currently, this is
  # called via Kernel#fork, Process.fork, and IO.popen with `"-"`.
  #
  # This method is not for casual code but for application monitoring libraries.
  # You can add custom code before and after fork events by overriding this
  # method.
  #
  def self._fork: () -> Integer

  # <!--
  #   rdoc-file=ruby.c
  #   - Process.argv0  -> frozen_string
  # -->
  # Returns the name of the script being executed.  The value is not affected by
  # assigning a new value to $0.
  #
  # This method first appeared in Ruby 2.1 to serve as a global variable free
  # means to get the script name.
  #
  def self.argv0: () -> String

  # <!--
  #   rdoc-file=process.c
  #   - Process.clock_getres(clock_id [, unit])   -> number
  # -->
  # Returns an estimate of the resolution of a `clock_id` using the POSIX
  # `clock_getres()` function.
  #
  # Note the reported resolution is often inaccurate on most platforms due to
  # underlying bugs for this function and therefore the reported resolution often
  # differs from the actual resolution of the clock in practice. Inaccurate
  # reported resolutions have been observed for various clocks including
  # CLOCK_MONOTONIC and CLOCK_MONOTONIC_RAW when using Linux, macOS, BSD or AIX
  # platforms, when using ARM processors, or when using virtualization.
  #
  # `clock_id` specifies a kind of clock. See the document of
  # `Process.clock_gettime` for details. `clock_id` can be a symbol as for
  # `Process.clock_gettime`.
  #
  # If the given `clock_id` is not supported, Errno::EINVAL is raised.
  #
  # `unit` specifies the type of the return value. `Process.clock_getres` accepts
  # `unit` as `Process.clock_gettime`. The default value, `:float_second`, is also
  # the same as `Process.clock_gettime`.
  #
  # `Process.clock_getres` also accepts `:hertz` as `unit`. `:hertz` means the
  # reciprocal of `:float_second`.
  #
  # `:hertz` can be used to obtain the exact value of the clock ticks per second
  # for the times() function and CLOCKS_PER_SEC for the clock() function.
  #
  # `Process.clock_getres(:TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID, :hertz)` returns
  # the clock ticks per second.
  #
  # `Process.clock_getres(:CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID, :hertz)` returns
  # CLOCKS_PER_SEC.
  #
  #     p Process.clock_getres(Process::CLOCK_MONOTONIC)
  #     #=> 1.0e-09
  #
  def self.clock_getres: (Symbol | Integer clock_id, ?Symbol unit) -> (Float | Integer)

  # <!--
  #   rdoc-file=process.c
  #   - Process.clock_gettime(clock_id [, unit])   -> number
  # -->
  # Returns a time returned by POSIX clock_gettime() function.
  #
  #     p Process.clock_gettime(Process::CLOCK_MONOTONIC)
  #     #=> 896053.968060096
  #
  # `clock_id` specifies a kind of clock. It is specified as a constant which
  # begins with `Process::CLOCK_` such as Process::CLOCK_REALTIME and
  # Process::CLOCK_MONOTONIC.
  #
  # The supported constants depends on OS and version. Ruby provides following
  # types of `clock_id` if available.
  #
  # CLOCK_REALTIME
  # :   SUSv2 to 4, Linux 2.5.63, FreeBSD 3.0, NetBSD 2.0, OpenBSD 2.1, macOS
  #     10.12, Windows-8/Server-2012
  # CLOCK_MONOTONIC
  # :   SUSv3 to 4, Linux 2.5.63, FreeBSD 3.0, NetBSD 2.0, OpenBSD 3.4, macOS
  #     10.12, Windows-2000
  # CLOCK_PROCESS_CPUTIME_ID
  # :   SUSv3 to 4, Linux 2.5.63, FreeBSD 9.3, OpenBSD 5.4, macOS 10.12
  # CLOCK_THREAD_CPUTIME_ID
  # :   SUSv3 to 4, Linux 2.5.63, FreeBSD 7.1, OpenBSD 5.4, macOS 10.12
  # CLOCK_VIRTUAL
  # :   FreeBSD 3.0, OpenBSD 2.1
  # CLOCK_PROF
  # :   FreeBSD 3.0, OpenBSD 2.1
  # CLOCK_REALTIME_FAST
  # :   FreeBSD 8.1
  # CLOCK_REALTIME_PRECISE
  # :   FreeBSD 8.1
  # CLOCK_REALTIME_COARSE
  # :   Linux 2.6.32
  # CLOCK_REALTIME_ALARM
  # :   Linux 3.0
  # CLOCK_MONOTONIC_FAST
  # :   FreeBSD 8.1
  # CLOCK_MONOTONIC_PRECISE
  # :   FreeBSD 8.1
  # CLOCK_MONOTONIC_COARSE
  # :   Linux 2.6.32
  # CLOCK_MONOTONIC_RAW
  # :   Linux 2.6.28, macOS 10.12
  # CLOCK_MONOTONIC_RAW_APPROX
  # :   macOS 10.12
  # CLOCK_BOOTTIME
  # :   Linux 2.6.39
  # CLOCK_BOOTTIME_ALARM
  # :   Linux 3.0
  # CLOCK_UPTIME
  # :   FreeBSD 7.0, OpenBSD 5.5
  # CLOCK_UPTIME_FAST
  # :   FreeBSD 8.1
  # CLOCK_UPTIME_RAW
  # :   macOS 10.12
  # CLOCK_UPTIME_RAW_APPROX
  # :   macOS 10.12
  # CLOCK_UPTIME_PRECISE
  # :   FreeBSD 8.1
  # CLOCK_SECOND
  # :   FreeBSD 8.1
  # CLOCK_TAI
  # :   Linux 3.10
  #
  #
  # Note that SUS stands for Single Unix Specification. SUS contains POSIX and
  # clock_gettime is defined in the POSIX part. SUS defines CLOCK_REALTIME
  # mandatory but CLOCK_MONOTONIC, CLOCK_PROCESS_CPUTIME_ID and
  # CLOCK_THREAD_CPUTIME_ID are optional.
  #
  # Also, several symbols are accepted as `clock_id`. There are emulations for
  # clock_gettime().
  #
  # For example, Process::CLOCK_REALTIME is defined as
  # `:GETTIMEOFDAY_BASED_CLOCK_REALTIME` when clock_gettime() is not available.
  #
  # Emulations for `CLOCK_REALTIME`:
  # :GETTIMEOFDAY_BASED_CLOCK_REALTIME
  # :   Use gettimeofday() defined by SUS. (SUSv4 obsoleted it, though.) The
  #     resolution is 1 microsecond.
  # :TIME_BASED_CLOCK_REALTIME
  # :   Use time() defined by ISO C. The resolution is 1 second.
  #
  #
  # Emulations for `CLOCK_MONOTONIC`:
  # :MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC
  # :   Use mach_absolute_time(), available on Darwin. The resolution is CPU
  #     dependent.
  # :TIMES_BASED_CLOCK_MONOTONIC
  # :   Use the result value of times() defined by POSIX. POSIX defines it as
  #     "times() shall return the elapsed real time, in clock ticks, since an
  #     arbitrary point in the past (for example, system start-up time)". For
  #     example, GNU/Linux returns a value based on jiffies and it is monotonic.
  #     However, 4.4BSD uses gettimeofday() and it is not monotonic. (FreeBSD uses
  #     clock_gettime(CLOCK_MONOTONIC) instead, though.) The resolution is the
  #     clock tick. "getconf CLK_TCK" command shows the clock ticks per second.
  #     (The clock ticks per second is defined by HZ macro in older systems.) If
  #     it is 100 and clock_t is 32 bits integer type, the resolution is 10
  #     millisecond and cannot represent over 497 days.
  #
  #
  # Emulations for `CLOCK_PROCESS_CPUTIME_ID`:
  # :GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID
  # :   Use getrusage() defined by SUS. getrusage() is used with RUSAGE_SELF to
  #     obtain the time only for the calling process (excluding the time for child
  #     processes). The result is addition of user time (ru_utime) and system time
  #     (ru_stime). The resolution is 1 microsecond.
  # :TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID
  # :   Use times() defined by POSIX. The result is addition of user time
  #     (tms_utime) and system time (tms_stime). tms_cutime and tms_cstime are
  #     ignored to exclude the time for child processes. The resolution is the
  #     clock tick. "getconf CLK_TCK" command shows the clock ticks per second.
  #     (The clock ticks per second is defined by HZ macro in older systems.) If
  #     it is 100, the resolution is 10 millisecond.
  # :CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID
  # :   Use clock() defined by ISO C. The resolution is 1/CLOCKS_PER_SEC.
  #     CLOCKS_PER_SEC is the C-level macro defined by time.h. SUS defines
  #     CLOCKS_PER_SEC is 1000000. Non-Unix systems may define it a different
  #     value, though. If CLOCKS_PER_SEC is 1000000 as SUS, the resolution is 1
  #     microsecond. If CLOCKS_PER_SEC is 1000000 and clock_t is 32 bits integer
  #     type, it cannot represent over 72 minutes.
  #
  #
  # If the given `clock_id` is not supported, Errno::EINVAL is raised.
  #
  # `unit` specifies a type of the return value.
  #
  # :float_second
  # :   number of seconds as a float (default)
  # :float_millisecond
  # :   number of milliseconds as a float
  # :float_microsecond
  # :   number of microseconds as a float
  # :second
  # :   number of seconds as an integer
  # :millisecond
  # :   number of milliseconds as an integer
  # :microsecond
  # :   number of microseconds as an integer
  # :nanosecond
  # :   number of nanoseconds as an integer
  #
  #
  # The underlying function, clock_gettime(), returns a number of nanoseconds.
  # Float object (IEEE 754 double) is not enough to represent the return value for
  # CLOCK_REALTIME. If the exact nanoseconds value is required, use `:nanoseconds`
  # as the `unit`.
  #
  # The origin (zero) of the returned value varies. For example, system start up
  # time, process start up time, the Epoch, etc.
  #
  # The origin in CLOCK_REALTIME is defined as the Epoch (1970-01-01 00:00:00
  # UTC). But some systems count leap seconds and others doesn't. So the result
  # can be interpreted differently across systems. Time.now is recommended over
  # CLOCK_REALTIME.
  #
  def self.clock_gettime: (Symbol | Integer clock_id) -> Float
                        | (Symbol | Integer clock_id, :float_second | :float_millisecond | :float_microsecond unit) -> Float
                        | (Symbol | Integer clock_id, :second | :millisecond | :microsecond | :nanosecond unit) -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process.daemon()                        -> 0
  #   - Process.daemon(nochdir=nil,noclose=nil) -> 0
  # -->
  # Detach the process from controlling terminal and run in the background as
  # system daemon.  Unless the argument nochdir is true (i.e. non false), it
  # changes the current working directory to the root ("/"). Unless the argument
  # noclose is true, daemon() will redirect standard input, standard output and
  # standard error to /dev/null. Return zero on success, or raise one of Errno::*.
  #
  def self.daemon: (?untyped nochdir, ?untyped noclose) -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process.detach(pid)   -> thread
  # -->
  # Some operating systems retain the status of terminated child processes until
  # the parent collects that status (normally using some variant of `wait()`). If
  # the parent never collects this status, the child stays around as a *zombie*
  # process. Process::detach prevents this by setting up a separate Ruby thread
  # whose sole job is to reap the status of the process *pid* when it terminates.
  # Use #detach only when you do not intend to explicitly wait for the child to
  # terminate.
  #
  # The waiting thread returns the exit status of the detached process when it
  # terminates, so you can use Thread#join to know the result.  If specified *pid*
  # is not a valid child process ID, the thread returns `nil` immediately.
  #
  # The waiting thread has #pid method which returns the pid.
  #
  # In this first example, we don't reap the first child process, so it appears as
  # a zombie in the process status display.
  #
  #     p1 = fork { sleep 0.1 }
  #     p2 = fork { sleep 0.2 }
  #     Process.waitpid(p2)
  #     sleep 2
  #     system("ps -ho pid,state -p #{p1}")
  #
  # *produces:*
  #
  #     27389 Z
  #
  # In the next example, Process::detach is used to reap the child automatically.
  #
  #     p1 = fork { sleep 0.1 }
  #     p2 = fork { sleep 0.2 }
  #     Process.detach(p1)
  #     Process.waitpid(p2)
  #     sleep 2
  #     system("ps -ho pid,state -p #{p1}")
  #
  # *(produces no output)*
  #
  def self.detach: (Integer pid) -> Thread

  # <!--
  #   rdoc-file=process.c
  #   - Process.egid          -> integer
  #   - Process::GID.eid      -> integer
  #   - Process::Sys.geteid   -> integer
  # -->
  # Returns the effective group ID for this process. Not available on all
  # platforms.
  #
  #     Process.egid   #=> 500
  #
  def self.egid: () -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process.egid = integer   -> integer
  # -->
  # Sets the effective group ID for this process. Not available on all platforms.
  #
  def self.egid=: (Integer arg0) -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process.euid           -> integer
  #   - Process::UID.eid       -> integer
  #   - Process::Sys.geteuid   -> integer
  # -->
  # Returns the effective user ID for this process.
  #
  #     Process.euid   #=> 501
  #
  def self.euid: () -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process.euid= user
  # -->
  # Sets the effective user ID for this process. Not available on all platforms.
  #
  def self.euid=: (Integer arg0) -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process.getpgid(pid)   -> integer
  # -->
  # Returns the process group ID for the given process id. Not available on all
  # platforms.
  #
  #     Process.getpgid(Process.ppid())   #=> 25527
  #
  def self.getpgid: (Integer pid) -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process.getpgrp   -> integer
  # -->
  # Returns the process group ID for this process. Not available on all platforms.
  #
  #     Process.getpgid(0)   #=> 25527
  #     Process.getpgrp      #=> 25527
  #
  def self.getpgrp: () -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process.getpriority(kind, integer)   -> integer
  # -->
  # Gets the scheduling priority for specified process, process group, or user.
  # *kind* indicates the kind of entity to find: one of Process::PRIO_PGRP,
  # Process::PRIO_USER, or Process::PRIO_PROCESS. *integer* is an id indicating
  # the particular process, process group, or user (an id of 0 means *current*).
  # Lower priorities are more favorable for scheduling. Not available on all
  # platforms.
  #
  #     Process.getpriority(Process::PRIO_USER, 0)      #=> 19
  #     Process.getpriority(Process::PRIO_PROCESS, 0)   #=> 19
  #
  def self.getpriority: (Integer kind, Integer arg0) -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process.getrlimit(resource)   -> [cur_limit, max_limit]
  # -->
  # Gets the resource limit of the process. *cur_limit* means current (soft) limit
  # and *max_limit* means maximum (hard) limit.
  #
  # *resource* indicates the kind of resource to limit. It is specified as a
  # symbol such as `:CORE`, a string such as `"CORE"` or a constant such as
  # Process::RLIMIT_CORE. See Process.setrlimit for details.
  #
  # *cur_limit* and *max_limit* may be Process::RLIM_INFINITY,
  # Process::RLIM_SAVED_MAX or Process::RLIM_SAVED_CUR. See Process.setrlimit and
  # the system getrlimit(2) manual for details.
  #
  def self.getrlimit: (Symbol | String | Integer resource) -> [ Integer, Integer ]

  # <!--
  #   rdoc-file=process.c
  #   - Process.getsid()      -> integer
  #   - Process.getsid(pid)   -> integer
  # -->
  # Returns the session ID for the given process id. If not given, return current
  # process sid. Not available on all platforms.
  #
  #     Process.getsid()                #=> 27422
  #     Process.getsid(0)               #=> 27422
  #     Process.getsid(Process.pid())   #=> 27422
  #
  def self.getsid: (?Integer pid) -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process.gid           -> integer
  #   - Process::GID.rid      -> integer
  #   - Process::Sys.getgid   -> integer
  # -->
  # Returns the (real) group ID for this process.
  #
  #     Process.gid   #=> 500
  #
  def self.gid: () -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process.gid= integer   -> integer
  # -->
  # Sets the group ID for this process.
  #
  def self.gid=: (Integer arg0) -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process.groups   -> array
  # -->
  # Get an Array of the group IDs in the supplemental group access list for this
  # process.
  #
  #     Process.groups   #=> [27, 6, 10, 11]
  #
  # Note that this method is just a wrapper of getgroups(2). This means that the
  # following characteristics of the result completely depend on your system:
  #
  # *   the result is sorted
  # *   the result includes effective GIDs
  # *   the result does not include duplicated GIDs
  #
  #
  # You can make sure to get a sorted unique GID list of the current process by
  # this expression:
  #
  #     Process.groups.uniq.sort
  #
  def self.groups: () -> ::Array[Integer]

  # <!--
  #   rdoc-file=process.c
  #   - Process.groups= array   -> array
  # -->
  # Set the supplemental group access list to the given Array of group IDs.
  #
  #     Process.groups   #=> [0, 1, 2, 3, 4, 6, 10, 11, 20, 26, 27]
  #     Process.groups = [27, 6, 10, 11]   #=> [27, 6, 10, 11]
  #     Process.groups   #=> [27, 6, 10, 11]
  #
  def self.groups=: (::Array[Integer] arg0) -> ::Array[Integer]

  # <!--
  #   rdoc-file=process.c
  #   - Process.initgroups(username, gid)   -> array
  # -->
  # Initializes the supplemental group access list by reading the system group
  # database and using all groups of which the given user is a member. The group
  # with the specified *gid* is also added to the list. Returns the resulting
  # Array of the gids of all the groups in the supplementary group access list.
  # Not available on all platforms.
  #
  #     Process.groups   #=> [0, 1, 2, 3, 4, 6, 10, 11, 20, 26, 27]
  #     Process.initgroups( "mgranger", 30 )   #=> [30, 6, 10, 11]
  #     Process.groups   #=> [30, 6, 10, 11]
  #
  def self.initgroups: (String username, Integer gid) -> ::Array[Integer]

  # <!--
  #   rdoc-file=process.c
  #   - Process.kill(signal, pid, ...)    -> integer
  # -->
  # Sends the given signal to the specified process id(s) if *pid* is positive. If
  # *pid* is zero, *signal* is sent to all processes whose group ID is equal to
  # the group ID of the process. If *pid* is negative, results are dependent on
  # the operating system. *signal* may be an integer signal number or a POSIX
  # signal name (either with or without a `SIG` prefix). If *signal* is negative
  # (or starts with a minus sign), kills process groups instead of processes. Not
  # all signals are available on all platforms. The keys and values of Signal.list
  # are known signal names and numbers, respectively.
  #
  #     pid = fork do
  #        Signal.trap("HUP") { puts "Ouch!"; exit }
  #        # ... do some work ...
  #     end
  #     # ...
  #     Process.kill("HUP", pid)
  #     Process.wait
  #
  # *produces:*
  #
  #     Ouch!
  #
  # If *signal* is an integer but wrong for signal, Errno::EINVAL or RangeError
  # will be raised.  Otherwise unless *signal* is a String or a Symbol, and a
  # known signal name, ArgumentError will be raised.
  #
  # Also, Errno::ESRCH or RangeError for invalid *pid*, Errno::EPERM when failed
  # because of no privilege, will be raised.  In these cases, signals may have
  # been sent to preceding processes.
  #
  def self.kill: (Integer | Symbol | String signal, *Integer pids) -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process.maxgroups   -> integer
  # -->
  # Returns the maximum number of gids allowed in the supplemental group access
  # list.
  #
  #     Process.maxgroups   #=> 32
  #
  def self.maxgroups: () -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process.maxgroups= integer   -> integer
  # -->
  # Sets the maximum number of gids allowed in the supplemental group access list.
  #
  def self.maxgroups=: (Integer arg0) -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process.pid   -> integer
  # -->
  # Returns the process id of this process. Not available on all platforms.
  #
  #     Process.pid   #=> 27415
  #
  def self.pid: () -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process.ppid   -> integer
  # -->
  # Returns the process id of the parent of this process. Returns untrustworthy
  # value on Win32/64. Not available on all platforms.
  #
  #     puts "I am #{Process.pid}"
  #     Process.fork { puts "Dad is #{Process.ppid}" }
  #
  # *produces:*
  #
  #     I am 27417
  #     Dad is 27417
  #
  def self.ppid: () -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process.setpgid(pid, integer)   -> 0
  # -->
  # Sets the process group ID of *pid* (0 indicates this process) to *integer*.
  # Not available on all platforms.
  #
  def self.setpgid: (Integer pid, Integer arg0) -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process.setpriority(kind, integer, priority)   -> 0
  # -->
  # See Process.getpriority.
  #
  #     Process.setpriority(Process::PRIO_USER, 0, 19)      #=> 0
  #     Process.setpriority(Process::PRIO_PROCESS, 0, 19)   #=> 0
  #     Process.getpriority(Process::PRIO_USER, 0)          #=> 19
  #     Process.getpriority(Process::PRIO_PROCESS, 0)       #=> 19
  #
  def self.setpriority: (Integer kind, Integer arg0, Integer priority) -> Integer

  # <!--
  #   rdoc-file=ruby.c
  #   - Process.setproctitle(string)  -> string
  # -->
  # Sets the process title that appears on the ps(1) command.  Not necessarily
  # effective on all platforms.  No exception will be raised regardless of the
  # result, nor will NotImplementedError be raised even if the platform does not
  # support the feature.
  #
  # Calling this method does not affect the value of $0.
  #
  #     Process.setproctitle('myapp: worker #%d' % worker_id)
  #
  # This method first appeared in Ruby 2.1 to serve as a global variable free
  # means to change the process title.
  #
  def self.setproctitle: (String arg0) -> String

  # <!--
  #   rdoc-file=process.c
  #   - Process.setrlimit(resource, cur_limit, max_limit)        -> nil
  #   - Process.setrlimit(resource, cur_limit)                   -> nil
  # -->
  # Sets the resource limit of the process. *cur_limit* means current (soft) limit
  # and *max_limit* means maximum (hard) limit.
  #
  # If *max_limit* is not given, *cur_limit* is used.
  #
  # *resource* indicates the kind of resource to limit. It should be a symbol such
  # as `:CORE`, a string such as `"CORE"` or a constant such as
  # Process::RLIMIT_CORE. The available resources are OS dependent. Ruby may
  # support following resources.
  #
  # AS
  # :   total available memory (bytes) (SUSv3, NetBSD, FreeBSD, OpenBSD but
  #     4.4BSD-Lite)
  # CORE
  # :   core size (bytes) (SUSv3)
  # CPU
  # :   CPU time (seconds) (SUSv3)
  # DATA
  # :   data segment (bytes) (SUSv3)
  # FSIZE
  # :   file size (bytes) (SUSv3)
  # MEMLOCK
  # :   total size for mlock(2) (bytes) (4.4BSD, GNU/Linux)
  # MSGQUEUE
  # :   allocation for POSIX message queues (bytes) (GNU/Linux)
  # NICE
  # :   ceiling on process's nice(2) value (number) (GNU/Linux)
  # NOFILE
  # :   file descriptors (number) (SUSv3)
  # NPROC
  # :   number of processes for the user (number) (4.4BSD, GNU/Linux)
  # RSS
  # :   resident memory size (bytes) (4.2BSD, GNU/Linux)
  # RTPRIO
  # :   ceiling on the process's real-time priority (number) (GNU/Linux)
  # RTTIME
  # :   CPU time for real-time process (us) (GNU/Linux)
  # SBSIZE
  # :   all socket buffers (bytes) (NetBSD, FreeBSD)
  # SIGPENDING
  # :   number of queued signals allowed (signals) (GNU/Linux)
  # STACK
  # :   stack size (bytes) (SUSv3)
  #
  #
  # *cur_limit* and *max_limit* may be `:INFINITY`, `"INFINITY"` or
  # Process::RLIM_INFINITY, which means that the resource is not limited. They may
  # be Process::RLIM_SAVED_MAX, Process::RLIM_SAVED_CUR and corresponding symbols
  # and strings too. See system setrlimit(2) manual for details.
  #
  # The following example raises the soft limit of core size to the hard limit to
  # try to make core dump possible.
  #
  #     Process.setrlimit(:CORE, Process.getrlimit(:CORE)[1])
  #
  def self.setrlimit: (Symbol | String | Integer resource, Integer cur_limit, ?Integer max_limit) -> nil

  # <!--
  #   rdoc-file=process.c
  #   - Process.setsid   -> integer
  # -->
  # Establishes this process as a new session and process group leader, with no
  # controlling tty. Returns the session id. Not available on all platforms.
  #
  #     Process.setsid   #=> 27422
  #
  def self.setsid: () -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process.times   -> aProcessTms
  # -->
  # Returns a `Tms` structure (see Process::Tms) that contains user and system CPU
  # times for this process, and also for children processes.
  #
  #     t = Process.times
  #     [ t.utime, t.stime, t.cutime, t.cstime ]   #=> [0.0, 0.02, 0.00, 0.00]
  #
  def self.times: () -> Process::Tms

  # <!--
  #   rdoc-file=process.c
  #   - Process.uid           -> integer
  #   - Process::UID.rid      -> integer
  #   - Process::Sys.getuid   -> integer
  # -->
  # Returns the (real) user ID of this process.
  #
  #     Process.uid   #=> 501
  #
  def self.uid: () -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process.uid= user   -> numeric
  # -->
  # Sets the (user) user ID for this process. Not available on all platforms.
  #
  def self.uid=: (Integer user) -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process.wait()                     -> integer
  #   - Process.wait(pid=-1, flags=0)      -> integer
  #   - Process.waitpid(pid=-1, flags=0)   -> integer
  # -->
  # Waits for a child process to exit, returns its process id, and sets `$?` to a
  # Process::Status object containing information on that process. Which child it
  # waits on depends on the value of *pid*:
  #
  # > 0
  # :   Waits for the child whose process ID equals *pid*.
  #
  # 0
  # :   Waits for any child whose process group ID equals that of the calling
  #     process.
  #
  # -1
  # :   Waits for any child process (the default if no *pid* is given).
  #
  # < -1
  # :   Waits for any child whose process group ID equals the absolute value of
  #     *pid*.
  #
  #
  # The *flags* argument may be a logical or of the flag values Process::WNOHANG
  # (do not block if no child available) or Process::WUNTRACED (return stopped
  # children that haven't been reported). Not all flags are available on all
  # platforms, but a flag value of zero will work on all platforms.
  #
  # Calling this method raises a SystemCallError if there are no child processes.
  # Not available on all platforms.
  #
  #     include Process
  #     fork { exit 99 }                 #=> 27429
  #     wait                             #=> 27429
  #     $?.exitstatus                    #=> 99
  #
  #     pid = fork { sleep 3 }           #=> 27440
  #     Time.now                         #=> 2008-03-08 19:56:16 +0900
  #     waitpid(pid, Process::WNOHANG)   #=> nil
  #     Time.now                         #=> 2008-03-08 19:56:16 +0900
  #     waitpid(pid, 0)                  #=> 27440
  #     Time.now                         #=> 2008-03-08 19:56:19 +0900
  #
  def self.wait: (?Integer pid, ?Integer flags) -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process.wait2(pid=-1, flags=0)      -> [pid, status]
  #   - Process.waitpid2(pid=-1, flags=0)   -> [pid, status]
  # -->
  # Waits for a child process to exit (see Process::waitpid for exact semantics)
  # and returns an array containing the process id and the exit status (a
  # Process::Status object) of that child. Raises a SystemCallError if there are
  # no child processes.
  #
  #     Process.fork { exit 99 }   #=> 27437
  #     pid, status = Process.wait2
  #     pid                        #=> 27437
  #     status.exitstatus          #=> 99
  #
  def self.wait2: (?Integer pid, ?Integer flags) -> [ Integer, Process::Status ]

  # <!--
  #   rdoc-file=process.c
  #   - Process.waitall   -> [ [pid1,status1], ...]
  # -->
  # Waits for all children, returning an array of *pid*/*status* pairs (where
  # *status* is a Process::Status object).
  #
  #     fork { sleep 0.2; exit 2 }   #=> 27432
  #     fork { sleep 0.1; exit 1 }   #=> 27433
  #     fork {            exit 0 }   #=> 27434
  #     p Process.waitall
  #
  # *produces*:
  #
  #     [[30982, #<Process::Status: pid 30982 exit 0>],
  #      [30979, #<Process::Status: pid 30979 exit 1>],
  #      [30976, #<Process::Status: pid 30976 exit 2>]]
  #
  def self.waitall: () -> ::Array[[ Integer, Process::Status ]]

  # <!--
  #   rdoc-file=process.c
  #   - Process.wait()                     -> integer
  #   - Process.wait(pid=-1, flags=0)      -> integer
  #   - Process.waitpid(pid=-1, flags=0)   -> integer
  # -->
  # Waits for a child process to exit, returns its process id, and sets `$?` to a
  # Process::Status object containing information on that process. Which child it
  # waits on depends on the value of *pid*:
  #
  # > 0
  # :   Waits for the child whose process ID equals *pid*.
  #
  # 0
  # :   Waits for any child whose process group ID equals that of the calling
  #     process.
  #
  # -1
  # :   Waits for any child process (the default if no *pid* is given).
  #
  # < -1
  # :   Waits for any child whose process group ID equals the absolute value of
  #     *pid*.
  #
  #
  # The *flags* argument may be a logical or of the flag values Process::WNOHANG
  # (do not block if no child available) or Process::WUNTRACED (return stopped
  # children that haven't been reported). Not all flags are available on all
  # platforms, but a flag value of zero will work on all platforms.
  #
  # Calling this method raises a SystemCallError if there are no child processes.
  # Not available on all platforms.
  #
  #     include Process
  #     fork { exit 99 }                 #=> 27429
  #     wait                             #=> 27429
  #     $?.exitstatus                    #=> 99
  #
  #     pid = fork { sleep 3 }           #=> 27440
  #     Time.now                         #=> 2008-03-08 19:56:16 +0900
  #     waitpid(pid, Process::WNOHANG)   #=> nil
  #     Time.now                         #=> 2008-03-08 19:56:16 +0900
  #     waitpid(pid, 0)                  #=> 27440
  #     Time.now                         #=> 2008-03-08 19:56:19 +0900
  #
  def self.waitpid: (?Integer pid, ?Integer flags) -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process.wait2(pid=-1, flags=0)      -> [pid, status]
  #   - Process.waitpid2(pid=-1, flags=0)   -> [pid, status]
  # -->
  # Waits for a child process to exit (see Process::waitpid for exact semantics)
  # and returns an array containing the process id and the exit status (a
  # Process::Status object) of that child. Raises a SystemCallError if there are
  # no child processes.
  #
  #     Process.fork { exit 99 }   #=> 27437
  #     pid, status = Process.wait2
  #     pid                        #=> 27437
  #     status.exitstatus          #=> 99
  #
  def self.waitpid2: (?Integer pid, ?Integer flags) -> [ Integer, Process::Status ]
end

# <!-- rdoc-file=process.c -->
# see Process.clock_gettime
#
Process::CLOCK_BOOTTIME: Integer

# <!-- rdoc-file=process.c -->
# see Process.clock_gettime
#
Process::CLOCK_BOOTTIME_ALARM: Integer

# <!-- rdoc-file=process.c -->
# see Process.clock_gettime
#
Process::CLOCK_MONOTONIC: Integer

# <!-- rdoc-file=process.c -->
# see Process.clock_gettime
#
Process::CLOCK_MONOTONIC_COARSE: Integer

# <!-- rdoc-file=process.c -->
# see Process.clock_gettime
#
Process::CLOCK_MONOTONIC_RAW: Integer

# <!-- rdoc-file=process.c -->
# see Process.clock_gettime
#
Process::CLOCK_PROCESS_CPUTIME_ID: Integer

# <!-- rdoc-file=process.c -->
# see Process.clock_gettime
#
Process::CLOCK_REALTIME: Integer

# <!-- rdoc-file=process.c -->
# see Process.clock_gettime
#
Process::CLOCK_REALTIME_ALARM: Integer

# <!-- rdoc-file=process.c -->
# see Process.clock_gettime
#
Process::CLOCK_REALTIME_COARSE: Integer

# <!-- rdoc-file=process.c -->
# see Process.clock_gettime
#
Process::CLOCK_THREAD_CPUTIME_ID: Integer

# <!-- rdoc-file=process.c -->
# see Process.setpriority
#
Process::PRIO_PGRP: Integer

# <!-- rdoc-file=process.c -->
# see Process.setpriority
#
Process::PRIO_PROCESS: Integer

# <!-- rdoc-file=process.c -->
# see Process.setpriority
#
Process::PRIO_USER: Integer

# <!-- rdoc-file=process.c -->
# Maximum size of the process's virtual memory (address space) in bytes.
#
# see the system getrlimit(2) manual for details.
#
Process::RLIMIT_AS: Integer

# <!-- rdoc-file=process.c -->
# Maximum size of the core file.
#
# see the system getrlimit(2) manual for details.
#
Process::RLIMIT_CORE: Integer

# <!-- rdoc-file=process.c -->
# CPU time limit in seconds.
#
# see the system getrlimit(2) manual for details.
#
Process::RLIMIT_CPU: Integer

# <!-- rdoc-file=process.c -->
# Maximum size of the process's data segment.
#
# see the system getrlimit(2) manual for details.
#
Process::RLIMIT_DATA: Integer

# <!-- rdoc-file=process.c -->
# Maximum size of files that the process may create.
#
# see the system getrlimit(2) manual for details.
#
Process::RLIMIT_FSIZE: Integer

# <!-- rdoc-file=process.c -->
# Maximum number of bytes of memory that may be locked into RAM.
#
# see the system getrlimit(2) manual for details.
#
Process::RLIMIT_MEMLOCK: Integer

# <!-- rdoc-file=process.c -->
# Specifies the limit on the number of bytes that can be allocated for POSIX
# message queues for the real user ID of the calling process.
#
# see the system getrlimit(2) manual for details.
#
Process::RLIMIT_MSGQUEUE: Integer

# <!-- rdoc-file=process.c -->
# Specifies a ceiling to which the process's nice value can be raised.
#
# see the system getrlimit(2) manual for details.
#
Process::RLIMIT_NICE: Integer

# <!-- rdoc-file=process.c -->
# Specifies a value one greater than the maximum file descriptor number that can
# be opened by this process.
#
# see the system getrlimit(2) manual for details.
#
Process::RLIMIT_NOFILE: Integer

# <!-- rdoc-file=process.c -->
# The maximum number of processes that can be created for the real user ID of
# the calling process.
#
# see the system getrlimit(2) manual for details.
#
Process::RLIMIT_NPROC: Integer

# <!-- rdoc-file=process.c -->
# Specifies the limit (in pages) of the process's resident set.
#
# see the system getrlimit(2) manual for details.
#
Process::RLIMIT_RSS: Integer

# <!-- rdoc-file=process.c -->
# Specifies a ceiling on the real-time priority that may be set for this
# process.
#
# see the system getrlimit(2) manual for details.
#
Process::RLIMIT_RTPRIO: Integer

# <!-- rdoc-file=process.c -->
# Specifies limit on CPU time this process scheduled under a real-time
# scheduling policy can consume.
#
# see the system getrlimit(2) manual for details.
#
Process::RLIMIT_RTTIME: Integer

# <!-- rdoc-file=process.c -->
# Specifies a limit on the number of signals that may be queued for the real
# user ID of the calling process.
#
# see the system getrlimit(2) manual for details.
#
Process::RLIMIT_SIGPENDING: Integer

# <!-- rdoc-file=process.c -->
# Maximum size of the stack, in bytes.
#
# see the system getrlimit(2) manual for details.
#
Process::RLIMIT_STACK: Integer

# <!-- rdoc-file=process.c -->
# see Process.setrlimit
#
Process::RLIM_INFINITY: Integer

# <!-- rdoc-file=process.c -->
# see Process.setrlimit
#
Process::RLIM_SAVED_CUR: Integer

# <!-- rdoc-file=process.c -->
# see Process.setrlimit
#
Process::RLIM_SAVED_MAX: Integer

# <!-- rdoc-file=process.c -->
# see Process.wait
#
Process::WNOHANG: Integer

# <!-- rdoc-file=process.c -->
# see Process.wait
#
Process::WUNTRACED: Integer

# <!-- rdoc-file=process.c -->
# The Process::GID module contains a collection of module functions which can be
# used to portably get, set, and switch the current process's real, effective,
# and saved group IDs.
#
module Process::GID
  # <!--
  #   rdoc-file=process.c
  #   - Process::GID.change_privilege(group)   -> integer
  # -->
  # Change the current process's real and effective group ID to that specified by
  # *group*. Returns the new group ID. Not available on all platforms.
  #
  #     [Process.gid, Process.egid]          #=> [0, 0]
  #     Process::GID.change_privilege(33)    #=> 33
  #     [Process.gid, Process.egid]          #=> [33, 33]
  #
  def self.change_privilege: (Integer group) -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process.egid          -> integer
  #   - Process::GID.eid      -> integer
  #   - Process::Sys.geteid   -> integer
  # -->
  # Returns the effective group ID for this process. Not available on all
  # platforms.
  #
  #     Process.egid   #=> 500
  #
  def self.eid: () -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process::GID.from_name(name)   -> gid
  # -->
  # Get the group ID by the *name*. If the group is not found, `ArgumentError`
  # will be raised.
  #
  #     Process::GID.from_name("wheel") #=> 0
  #     Process::GID.from_name("nosuchgroup") #=> can't find group for nosuchgroup (ArgumentError)
  #
  def self.from_name: (String name) -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process::GID.grant_privilege(group)    -> integer
  #   - Process::GID.eid = group               -> integer
  # -->
  # Set the effective group ID, and if possible, the saved group ID of the process
  # to the given *group*. Returns the new effective group ID. Not available on all
  # platforms.
  #
  #     [Process.gid, Process.egid]          #=> [0, 0]
  #     Process::GID.grant_privilege(31)     #=> 33
  #     [Process.gid, Process.egid]          #=> [0, 33]
  #
  def self.grant_privilege: (Integer group) -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process::GID.re_exchange   -> integer
  # -->
  # Exchange real and effective group IDs and return the new effective group ID.
  # Not available on all platforms.
  #
  #     [Process.gid, Process.egid]   #=> [0, 33]
  #     Process::GID.re_exchange      #=> 0
  #     [Process.gid, Process.egid]   #=> [33, 0]
  #
  def self.re_exchange: () -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process::GID.re_exchangeable?   -> true or false
  # -->
  # Returns `true` if the real and effective group IDs of a process may be
  # exchanged on the current platform.
  #
  def self.re_exchangeable?: () -> bool

  # <!--
  #   rdoc-file=process.c
  #   - Process.gid           -> integer
  #   - Process::GID.rid      -> integer
  #   - Process::Sys.getgid   -> integer
  # -->
  # Returns the (real) group ID for this process.
  #
  #     Process.gid   #=> 500
  #
  def self.rid: () -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process::GID.sid_available?   -> true or false
  # -->
  # Returns `true` if the current platform has saved group ID functionality.
  #
  def self.sid_available?: () -> bool

  # <!--
  #   rdoc-file=process.c
  #   - Process::GID.switch              -> integer
  #   - Process::GID.switch {|| block}   -> object
  # -->
  # Switch the effective and real group IDs of the current process. If a *block*
  # is given, the group IDs will be switched back after the block is executed.
  # Returns the new effective group ID if called without a block, and the return
  # value of the block if one is given.
  #
  def self.switch: () -> Integer
                 | [T] () { () -> T } -> T

  def self.eid=: (Integer group) -> Integer
end

# <!-- rdoc-file=process.c -->
# Process::Status encapsulates the information on the status of a running or
# terminated system process. The built-in variable `$?` is either `nil` or a
# Process::Status object.
#
#     fork { exit 99 }   #=> 26557
#     Process.wait       #=> 26557
#     $?.class           #=> Process::Status
#     $?.to_i            #=> 25344
#     $? >> 8            #=> 99
#     $?.stopped?        #=> false
#     $?.exited?         #=> true
#     $?.exitstatus      #=> 99
#
# Posix systems record information on processes using a 16-bit integer.  The
# lower bits record the process status (stopped, exited, signaled) and the upper
# bits possibly contain additional information (for example the program's return
# code in the case of exited processes). Pre Ruby 1.8, these bits were exposed
# directly to the Ruby program. Ruby now encapsulates these in a Process::Status
# object. To maximize compatibility, however, these objects retain a
# bit-oriented interface. In the descriptions that follow, when we talk about
# the integer value of *stat*, we're referring to this 16 bit value.
#
class Process::Status < Object
  # <!--
  #   rdoc-file=process.c
  #   - stat & num   -> integer
  # -->
  # Logical AND of the bits in *stat* with *num*.
  #
  #     fork { exit 0x37 }
  #     Process.wait
  #     sprintf('%04x', $?.to_i)       #=> "3700"
  #     sprintf('%04x', $? & 0x1e00)   #=> "1600"
  #
  def &: (Integer num) -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - stat == other   -> true or false
  # -->
  # Returns `true` if the integer value of *stat* equals *other*.
  #
  def ==: (untyped other) -> bool

  # <!--
  #   rdoc-file=process.c
  #   - stat >> num   -> integer
  # -->
  # Shift the bits in *stat* right *num* places.
  #
  #     fork { exit 99 }   #=> 26563
  #     Process.wait       #=> 26563
  #     $?.to_i            #=> 25344
  #     $? >> 8            #=> 99
  #
  def >>: (Integer num) -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - stat.coredump?   -> true or false
  # -->
  # Returns `true` if *stat* generated a coredump when it terminated. Not
  # available on all platforms.
  #
  def coredump?: () -> bool

  # <!--
  #   rdoc-file=process.c
  #   - stat.exited?   -> true or false
  # -->
  # Returns `true` if *stat* exited normally (for example using an `exit()` call
  # or finishing the program).
  #
  def exited?: () -> bool

  # <!--
  #   rdoc-file=process.c
  #   - stat.exitstatus   -> integer or nil
  # -->
  # Returns the least significant eight bits of the return code of *stat*. Only
  # available if #exited? is `true`.
  #
  #     fork { }           #=> 26572
  #     Process.wait       #=> 26572
  #     $?.exited?         #=> true
  #     $?.exitstatus      #=> 0
  #
  #     fork { exit 99 }   #=> 26573
  #     Process.wait       #=> 26573
  #     $?.exited?         #=> true
  #     $?.exitstatus      #=> 99
  #
  def exitstatus: () -> Integer?

  # <!--
  #   rdoc-file=process.c
  #   - stat.inspect   -> string
  # -->
  # Override the inspection method.
  #
  #     system("false")
  #     p $?.inspect #=> "#<Process::Status: pid 12861 exit 1>"
  #
  def inspect: () -> String

  # <!--
  #   rdoc-file=process.c
  #   - stat.pid   -> integer
  # -->
  # Returns the process ID that this status object represents.
  #
  #     fork { exit }   #=> 26569
  #     Process.wait    #=> 26569
  #     $?.pid          #=> 26569
  #
  def pid: () -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - stat.signaled?   -> true or false
  # -->
  # Returns `true` if *stat* terminated because of an uncaught signal.
  #
  def signaled?: () -> bool

  # <!--
  #   rdoc-file=process.c
  #   - stat.stopped?   -> true or false
  # -->
  # Returns `true` if this process is stopped. This is only returned if the
  # corresponding #wait call had the Process::WUNTRACED flag set.
  #
  def stopped?: () -> bool

  # <!--
  #   rdoc-file=process.c
  #   - stat.stopsig   -> integer or nil
  # -->
  # Returns the number of the signal that caused *stat* to stop (or `nil` if self
  # is not stopped).
  #
  def stopsig: () -> Integer?

  # <!--
  #   rdoc-file=process.c
  #   - stat.success?   -> true, false or nil
  # -->
  # Returns `true` if *stat* is successful, `false` if not. Returns `nil` if
  # #exited? is not `true`.
  #
  def success?: () -> bool

  # <!--
  #   rdoc-file=process.c
  #   - stat.termsig   -> integer or nil
  # -->
  # Returns the number of the signal that caused *stat* to terminate (or `nil` if
  # self was not terminated by an uncaught signal).
  #
  def termsig: () -> Integer?

  # <!--
  #   rdoc-file=process.c
  #   - stat.to_i     -> integer
  # -->
  # Returns the bits in *stat* as an Integer. Poking around in these bits is
  # platform dependent.
  #
  #     fork { exit 0xab }         #=> 26566
  #     Process.wait               #=> 26566
  #     sprintf('%04x', $?.to_i)   #=> "ab00"
  #
  def to_i: () -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - stat.to_s   -> string
  # -->
  # Show pid and exit status as a string.
  #
  #     system("false")
  #     p $?.to_s         #=> "pid 12766 exit 1"
  #
  def to_s: () -> String
end

# <!-- rdoc-file=process.c -->
# The Process::Sys module contains UID and GID functions which provide direct
# bindings to the system calls of the same names instead of the more-portable
# versions of the same functionality found in the Process, Process::UID, and
# Process::GID modules.
#
module Process::Sys
  # <!--
  #   rdoc-file=process.c
  #   - Process.euid           -> integer
  #   - Process::UID.eid       -> integer
  #   - Process::Sys.geteuid   -> integer
  # -->
  # Returns the effective user ID for this process.
  #
  #     Process.euid   #=> 501
  #
  def self.geteuid: () -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process.gid           -> integer
  #   - Process::GID.rid      -> integer
  #   - Process::Sys.getgid   -> integer
  # -->
  # Returns the (real) group ID for this process.
  #
  #     Process.gid   #=> 500
  #
  def self.getgid: () -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process.uid           -> integer
  #   - Process::UID.rid      -> integer
  #   - Process::Sys.getuid   -> integer
  # -->
  # Returns the (real) user ID of this process.
  #
  #     Process.uid   #=> 501
  #
  def self.getuid: () -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process::Sys.issetugid   -> true or false
  # -->
  # Returns `true` if the process was created as a result of an execve(2) system
  # call which had either of the setuid or setgid bits set (and extra privileges
  # were given as a result) or if it has changed any of its real, effective or
  # saved user or group IDs since it began execution.
  #
  def self.issetugid: () -> bool

  # <!--
  #   rdoc-file=process.c
  #   - Process::Sys.setegid(group)   -> nil
  # -->
  # Set the effective group ID of the calling process to *group*.  Not available
  # on all platforms.
  #
  def self.setegid: (Integer group) -> nil

  # <!--
  #   rdoc-file=process.c
  #   - Process::Sys.seteuid(user)   -> nil
  # -->
  # Set the effective user ID of the calling process to *user*.  Not available on
  # all platforms.
  #
  def self.seteuid: (Integer user) -> nil

  # <!--
  #   rdoc-file=process.c
  #   - Process::Sys.setgid(group)   -> nil
  # -->
  # Set the group ID of the current process to *group*. Not available on all
  # platforms.
  #
  def self.setgid: (Integer group) -> nil

  # <!--
  #   rdoc-file=process.c
  #   - Process::Sys.setregid(rid, eid)   -> nil
  # -->
  # Sets the (group) real and/or effective group IDs of the current process to
  # *rid* and *eid*, respectively. A value of `-1` for either means to leave that
  # ID unchanged. Not available on all platforms.
  #
  def self.setregid: (Integer rid, Integer eid) -> nil

  # <!--
  #   rdoc-file=process.c
  #   - Process::Sys.setresgid(rid, eid, sid)   -> nil
  # -->
  # Sets the (group) real, effective, and saved user IDs of the current process to
  # *rid*, *eid*, and *sid* respectively. A value of `-1` for any value means to
  # leave that ID unchanged. Not available on all platforms.
  #
  def self.setresgid: (Integer rid, Integer eid, Integer sid) -> nil

  # <!--
  #   rdoc-file=process.c
  #   - Process::Sys.setresuid(rid, eid, sid)   -> nil
  # -->
  # Sets the (user) real, effective, and saved user IDs of the current process to
  # *rid*, *eid*, and *sid* respectively. A value of `-1` for any value means to
  # leave that ID unchanged. Not available on all platforms.
  #
  def self.setresuid: (Integer rid, Integer eid, Integer sid) -> nil

  # <!--
  #   rdoc-file=process.c
  #   - Process::Sys.setreuid(rid, eid)   -> nil
  # -->
  # Sets the (user) real and/or effective user IDs of the current process to *rid*
  # and *eid*, respectively. A value of `-1` for either means to leave that ID
  # unchanged. Not available on all platforms.
  #
  def self.setreuid: (Integer rid, Integer eid) -> nil

  # <!--
  #   rdoc-file=process.c
  #   - Process::Sys.setrgid(group)   -> nil
  # -->
  # Set the real group ID of the calling process to *group*. Not available on all
  # platforms.
  #
  def self.setrgid: (Integer group) -> nil

  # <!--
  #   rdoc-file=process.c
  #   - Process::Sys.setruid(user)   -> nil
  # -->
  # Set the real user ID of the calling process to *user*. Not available on all
  # platforms.
  #
  def self.setruid: (Integer user) -> nil

  # <!--
  #   rdoc-file=process.c
  #   - Process::Sys.setuid(user)   -> nil
  # -->
  # Set the user ID of the current process to *user*. Not available on all
  # platforms.
  #
  def self.setuid: (Integer user) -> nil
end

# <!-- rdoc-file=process.c -->
# The Process::UID module contains a collection of module functions which can be
# used to portably get, set, and switch the current process's real, effective,
# and saved user IDs.
#
module Process::UID
  # <!--
  #   rdoc-file=process.c
  #   - Process::UID.change_privilege(user)   -> integer
  # -->
  # Change the current process's real and effective user ID to that specified by
  # *user*. Returns the new user ID. Not available on all platforms.
  #
  #     [Process.uid, Process.euid]          #=> [0, 0]
  #     Process::UID.change_privilege(31)    #=> 31
  #     [Process.uid, Process.euid]          #=> [31, 31]
  #
  def self.change_privilege: (Integer user) -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process.euid           -> integer
  #   - Process::UID.eid       -> integer
  #   - Process::Sys.geteuid   -> integer
  # -->
  # Returns the effective user ID for this process.
  #
  #     Process.euid   #=> 501
  #
  def self.eid: () -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process::UID.from_name(name)   -> uid
  # -->
  # Get the user ID by the *name*. If the user is not found, `ArgumentError` will
  # be raised.
  #
  #     Process::UID.from_name("root") #=> 0
  #     Process::UID.from_name("nosuchuser") #=> can't find user for nosuchuser (ArgumentError)
  #
  def self.from_name: (String name) -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process::UID.grant_privilege(user)   -> integer
  #   - Process::UID.eid= user               -> integer
  # -->
  # Set the effective user ID, and if possible, the saved user ID of the process
  # to the given *user*. Returns the new effective user ID. Not available on all
  # platforms.
  #
  #     [Process.uid, Process.euid]          #=> [0, 0]
  #     Process::UID.grant_privilege(31)     #=> 31
  #     [Process.uid, Process.euid]          #=> [0, 31]
  #
  def self.grant_privilege: (Integer user) -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process::UID.re_exchange   -> integer
  # -->
  # Exchange real and effective user IDs and return the new effective user ID. Not
  # available on all platforms.
  #
  #     [Process.uid, Process.euid]   #=> [0, 31]
  #     Process::UID.re_exchange      #=> 0
  #     [Process.uid, Process.euid]   #=> [31, 0]
  #
  def self.re_exchange: () -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process::UID.re_exchangeable?   -> true or false
  # -->
  # Returns `true` if the real and effective user IDs of a process may be
  # exchanged on the current platform.
  #
  def self.re_exchangeable?: () -> bool

  # <!--
  #   rdoc-file=process.c
  #   - Process.uid           -> integer
  #   - Process::UID.rid      -> integer
  #   - Process::Sys.getuid   -> integer
  # -->
  # Returns the (real) user ID of this process.
  #
  #     Process.uid   #=> 501
  #
  def self.rid: () -> Integer

  # <!--
  #   rdoc-file=process.c
  #   - Process::UID.sid_available?   -> true or false
  # -->
  # Returns `true` if the current platform has saved user ID functionality.
  #
  def self.sid_available?: () -> bool

  # <!--
  #   rdoc-file=process.c
  #   - Process::UID.switch              -> integer
  #   - Process::UID.switch {|| block}   -> object
  # -->
  # Switch the effective and real user IDs of the current process. If a *block* is
  # given, the user IDs will be switched back after the block is executed. Returns
  # the new effective user ID if called without a block, and the return value of
  # the block if one is given.
  #
  def self.switch: () -> Integer
                 | [T] () { () -> T } -> T

  def self.eid=: (Integer user) -> Integer
end

class Process::Tms < Struct[Float]
end

class Process::Waiter < Thread
  def pid: () -> Integer
end
