ctucx.git: nixfiles

ctucx' nixfiles

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 
75 
76 
77 
78 
79 
80 
81 
82 
83 
84 
85 
86 
87 
88 
89 
90 
91 
92 
93 
94 
95 
96 
{ stdenv, uhubctl, runCommand, writeText, ...}:

let
  uhubDaemon = writeText "uhubDaemon.c" ''
    #include <ctype.h>
    #include <stdlib.h>
    #include <stdio.h>

    #include <mach/mach_port.h>
    #include <mach/mach_interface.h>
    #include <mach/mach_init.h>

    #include <IOKit/pwr_mgt/IOPMLib.h>
    #include <IOKit/IOMessage.h>

    io_connect_t  root_port; // a reference to the Root Power Domain IOService

    void MySleepCallBack( void * refCon, io_service_t service, natural_t messageType, void * messageArgument ) {
        switch ( messageType ) {
            case kIOMessageCanSystemSleep:
                IOAllowPowerChange( root_port, (long)messageArgument );
                break;

            case kIOMessageSystemWillSleep:
                system("${uhubctl}/bin/uhubctl -n 0bda -p 2-2 -a off");
                IOAllowPowerChange( root_port, (long)messageArgument );
                break;

            case kIOMessageSystemWillPowerOn:
                system("${uhubctl}/bin/uhubctl -n 0bda -p 2-2 -a on");
                break;

            case kIOMessageSystemHasPoweredOn:
                //System has finished waking up...
            break;

            default:
                break;
        }
    }

    int main( int argc, char **argv ) {
        // notification port allocated by IORegisterForSystemPower
        IONotificationPortRef  notifyPortRef;

        // notifier object, used to deregister later
        io_object_t notifierObject;
        // this parameter is passed to the callback
        void*       refCon;

        // register to receive system sleep notifications
        root_port = IORegisterForSystemPower( refCon, &notifyPortRef, MySleepCallBack, &notifierObject );
        if ( root_port == 0 ) {
            printf("IORegisterForSystemPower failed\n");
            return 1;
        }

        // add the notification port to the application runloop
        CFRunLoopAddSource( CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(notifyPortRef), kCFRunLoopCommonModes );

        /* Start the run loop to receive sleep notifications. Don't call CFRunLoopRun if this code
           is running on the main thread of a Cocoa or Carbon application. Cocoa and Carbon
           manage the main thread's run loop for you as part of their event handling
           mechanisms.
        */
        CFRunLoopRun();

        //Not reached, CFRunLoopRun doesn't return in this case.
        return (0);
    }
  '';

  buildSymlinks = runCommand "macvim-build-symlinks" {} ''
    mkdir -p $out/bin
    ln -s /usr/bin/gcc $out/bin
  '';

in stdenv.mkDerivation {
  name = "uhubDaemon";
  src = ./.;

  nativeBuildInputs = [ buildSymlinks ];

  sandboxProfile = ''
     (allow file-read* file-write* process-exec mach-lookup)
     ; block homebrew dependencies
     (deny file-read* file-write* process-exec mach-lookup (subpath "/usr/local") (with no-log))
  '';

  buildPhase = "gcc -framework IOKit -framework Cocoa -lcurl -o uhubDaemon ${uhubDaemon}";

  installPhase = ''
    mkdir -p $out/bin
    cp uhubDaemon $out/bin/
  '';
}