カフェインでMacを眠らせない！

![DALL·E 2023-10-10 10.22.15 - Illustration of an elegant cyborg engineer, seated in a futuristic setting, holding a cup of coffee and deeply engrossed in developing an AI model on .png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52151/88d00906-16c7-4324-a300-c83f0737358f.png)

# はじめに

席を外して、戻ってきたらMacがスリープしていた、という経験は誰でもお持ちですね。使っていない時間はMacがスリープしてバッテリーの消費を節約してくれる、なんてありがたい機能なんでしょう。

ところが、場合によってはスリープしないでほしいケースもあると思います。
* サーバーにSSH接続して作業をしていた
* 巨大なファイルのダウンロード
* プレゼンテーション中のスクリーンのスリープの回避、等
です。

そんな時に活躍してくれる機能(コマンド)がcaffeinateコマンドです。

# 使い方

caffeinateは、MacOSが標準で提供するコマンドなので、manコマンドで詳細を確認できます。
```shells
man caffeinate
```
出力内容はこちらです。
```shells
CAFFEINATE(8)               System Manager's Manual              CAFFEINATE(8)

NAME
     caffeinate – prevent the system from sleeping on behalf of a utility

SYNOPSIS
     caffeinate [-disu] [-t timeout] [-w pid] [utility arguments...]

DESCRIPTION
     caffeinate creates assertions to alter system sleep behavior.  If no
     assertion flags are specified, caffeinate creates an assertion to prevent
     idle sleep.  If a utility is specified, caffeinate creates the assertions
     on the utility's behalf, and those assertions will persist for the
     duration of the utility's execution. Otherwise, caffeinate creates the
     assertions directly, and those assertions will persist until caffeinate
     exits.

     Available options:

     -d      Create an assertion to prevent the display from sleeping.

     -i      Create an assertion to prevent the system from idle sleeping.

     -m      Create an assertion to prevent the disk from idle sleeping.

     -s      Create an assertion to prevent the system from sleeping. This
             assertion is valid only when system is running on AC power.

     -u      Create an assertion to declare that user is active. If the
             display is off, this option turns the display on and prevents the
             display from going into idle sleep. If a timeout is not specified
             with '-t' option, then this assertion is taken with a default of
             5 second timeout.

     -t      Specifies the timeout value in seconds for which this assertion
             has to be valid. The assertion is dropped after the specified
             timeout. Timeout value is not used when an utility is invoked
             with this command.

     -w      Waits for the process with the specified pid to exit. Once the
             the process exits, the assertion is also released.  This option
             is ignored when used with utility option.

EXAMPLE
     caffeinate -i make
        caffeinate forks a process, execs "make" in it, and holds an assertion
     that prevents idle sleep as long as that process is running.

SEE ALSO
     pmset(1)

LOCATION
     /usr/bin/caffeinate

Darwin                         November 9, 2012                         Darwin
```

EXAMPLEの例は、makeコマンドが完了するまでスリープさせない、というものです。

Makefileに関連のソースコードとその依存性を記述します。実際のプロジェクトでは、大量のソースコードをコンパイルする必要があり、コンパイ終了まで数十分〜数時間かかる場合があります。
コンパイルしている間に一休み、と思い休憩から帰ってきたら、Macがスリープしていた、なんて笑えない状況もありますね:joy_cat:

その他に、実用的な使い方として、

例1: ずーっとスリープさせない

```shells
$ caffeinate -i
```
Ctrl-C でcaffeinateコマンドを中断させない限り、Macはスリープしません。

例2:指定した時間までスリープさせない

```shells
$ caffeinate -u -t スリープさせたくない時間(秒で指定する)
```

例3:あるプロセスが起動している間はスリープさせない
```shells
$ caffeinate -w pid
```
:::note
pidはpsコマンドもしくはアクティビティモニターで確認できます。
(アクティビティモニターの例)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52151/5b616e90-7cda-fe80-f40c-967ef465f27b.png)

:::


# どうやってスリープしないようにしているのか？

どんな方法を使っているのか気になって色々と調べていたら、なんと！ソースコードが公開されていました:bangbang:

https://opensource.apple.com/source/PowerManagement/PowerManagement-271.1/caffeinate/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52151/2aee0033-9e4e-3e19-71e3-609fc2b85138.png)




# 終わりに

久しぶりにC言語のソースコードを読みました。
caffeinateの実装は240行程度です。システム・コールを使っているから、という理由もありますが、システムコールを使ったMacOSプログラミングの参考にもなると思います。

# 参考

caffeinateのソースコード

https://opensource.apple.com/source/PowerManagement/PowerManagement-271.1/caffeinate/

CaffeinateのGitHub

https://github.com/getappbox/Caffeinate?tab=readme-ov-file