]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/sys_work_interval.c
xnu-4903.270.47.tar.gz
[apple/xnu.git] / bsd / kern / sys_work_interval.c
index bbfdd5e610547f0411193d8dbec8555b32a9fa4d..203086a1b638bb44a6015f919c32eae5f9605c10 100644 (file)
@@ -40,7 +40,7 @@
 
 int
 work_interval_ctl(__unused proc_t p, struct work_interval_ctl_args *uap,
-                  __unused int32_t *retval)
+    __unused int32_t *retval)
 {
        uint32_t        operation = uap->operation;
        int             error = 0;
@@ -51,117 +51,128 @@ work_interval_ctl(__unused proc_t p, struct work_interval_ctl_args *uap,
        struct kern_work_interval_create_args create_args;
 
        switch (operation) {
-               case WORK_INTERVAL_OPERATION_CREATE:
-                       return ENOTSUP;
-               case WORK_INTERVAL_OPERATION_CREATE2:
-                       if (uap->arg == USER_ADDR_NULL || uap->work_interval_id != 0)
-                               return EINVAL;
-                       if (uap->len < sizeof(create_params))
-                               return EINVAL;
-
-                       if ((error = copyin(uap->arg, &create_params, sizeof(create_params))))
-                               return error;
-
-                       if ((error = priv_check_cred(kauth_cred_get(), PRIV_WORK_INTERVAL, 0)) != 0) {
-                               return error;
-                       }
-
-                       create_args = (struct kern_work_interval_create_args) {
-                               .wica_id            = create_params.wicp_id,
-                               .wica_port          = create_params.wicp_port,
-                               .wica_create_flags  = create_params.wicp_create_flags,
-                       };
-
-                       kret = kern_work_interval_create(current_thread(), &create_args);
-
-                       /* thread already has a work interval */
-                       if (kret == KERN_FAILURE)
-                               return EALREADY;
-
-                       /* port copyout failed */
-                       if (kret == KERN_RESOURCE_SHORTAGE)
-                               return ENOMEM;
-
-                       /* some other failure */
-                       if (kret != KERN_SUCCESS)
-                               return EINVAL;
-
-                       create_params = (struct work_interval_create_params) {
-                               .wicp_id = create_args.wica_id,
-                               .wicp_port = create_args.wica_port,
-                               .wicp_create_flags = create_args.wica_create_flags,
-                       };
-
-                       if ((error = copyout(&create_params, uap->arg, sizeof(create_params)))) {
-                               kern_work_interval_destroy(current_thread(), create_args.wica_id);
-                               return error;
-                       }
-                       break;
-               case WORK_INTERVAL_OPERATION_DESTROY:
-                       if (uap->arg != USER_ADDR_NULL || uap->work_interval_id == 0) {
-                               return EINVAL;
-                       }
-
-                       /*
-                        * No privilege check, we assume a previous WORK_INTERVAL_OPERATION_CREATE
-                        * operation would have allocated a work interval ID for the current
-                        * thread, which the scheduler will validate.
-                        */
-                       kret = kern_work_interval_destroy(current_thread(), uap->work_interval_id);
-                       if (kret != KERN_SUCCESS)
-                               return EINVAL;
-
-                       break;
-               case WORK_INTERVAL_OPERATION_NOTIFY:
-                       if (uap->arg == USER_ADDR_NULL || uap->work_interval_id == 0)
-                               return EINVAL;
-
-                       if (uap->len < sizeof(notification))
-                               return EINVAL;
-
-                       /*
-                        * No privilege check, we assume a previous WORK_INTERVAL_OPERATION_CREATE
-                        * operation would have allocated a work interval ID for the current
-                        * thread, which the scheduler will validate.
-                        */
-                       if ((error = copyin(uap->arg, &notification, sizeof(notification))))
-                               return error;
-
-                       struct kern_work_interval_args kwi_args = {
-                               .work_interval_id   = uap->work_interval_id,
-                               .start              = notification.start,
-                               .finish             = notification.finish,
-                               .deadline           = notification.deadline,
-                               .next_start         = notification.next_start,
-                               .notify_flags       = notification.notify_flags,
-                               .create_flags       = notification.create_flags,
-                       };
-
-                       kret = kern_work_interval_notify(current_thread(), &kwi_args);
-                       if (kret != KERN_SUCCESS)
-                               return EINVAL;
-
-                       break;
-               case WORK_INTERVAL_OPERATION_JOIN:
-                       if (uap->arg != USER_ADDR_NULL) {
-                               return EINVAL;
-                       }
-
-                       /*
-                        * No privilege check, because the work interval port
-                        * is a capability.
-                        */
-                       kret = kern_work_interval_join(current_thread(),
-                                                      (mach_port_name_t)uap->work_interval_id);
-                       if (kret != KERN_SUCCESS)
-                               return EINVAL;
-
-                       break;
-
-               default:
-                       return ENOTSUP;
+       case WORK_INTERVAL_OPERATION_CREATE:
+               return ENOTSUP;
+       case WORK_INTERVAL_OPERATION_CREATE2:
+               if (uap->arg == USER_ADDR_NULL || uap->work_interval_id != 0) {
+                       return EINVAL;
+               }
+               if (uap->len < sizeof(create_params)) {
+                       return EINVAL;
+               }
+
+               if ((error = copyin(uap->arg, &create_params, sizeof(create_params)))) {
+                       return error;
+               }
+
+               if ((error = priv_check_cred(kauth_cred_get(), PRIV_WORK_INTERVAL, 0)) != 0) {
+                       return error;
+               }
+
+               create_args = (struct kern_work_interval_create_args) {
+                       .wica_id            = create_params.wicp_id,
+                       .wica_port          = create_params.wicp_port,
+                       .wica_create_flags  = create_params.wicp_create_flags,
+               };
+
+               kret = kern_work_interval_create(current_thread(), &create_args);
+
+               /* thread already has a work interval */
+               if (kret == KERN_FAILURE) {
+                       return EALREADY;
+               }
+
+               /* port copyout failed */
+               if (kret == KERN_RESOURCE_SHORTAGE) {
+                       return ENOMEM;
+               }
+
+               /* some other failure */
+               if (kret != KERN_SUCCESS) {
+                       return EINVAL;
+               }
+
+               create_params = (struct work_interval_create_params) {
+                       .wicp_id = create_args.wica_id,
+                       .wicp_port = create_args.wica_port,
+                       .wicp_create_flags = create_args.wica_create_flags,
+               };
+
+               if ((error = copyout(&create_params, uap->arg, sizeof(create_params)))) {
+                       kern_work_interval_destroy(current_thread(), create_args.wica_id);
+                       return error;
+               }
+               break;
+       case WORK_INTERVAL_OPERATION_DESTROY:
+               if (uap->arg != USER_ADDR_NULL || uap->work_interval_id == 0) {
+                       return EINVAL;
+               }
+
+               /*
+                * No privilege check, we assume a previous WORK_INTERVAL_OPERATION_CREATE
+                * operation would have allocated a work interval ID for the current
+                * thread, which the scheduler will validate.
+                */
+               kret = kern_work_interval_destroy(current_thread(), uap->work_interval_id);
+               if (kret != KERN_SUCCESS) {
+                       return EINVAL;
+               }
+
+               break;
+       case WORK_INTERVAL_OPERATION_NOTIFY:
+               if (uap->arg == USER_ADDR_NULL || uap->work_interval_id == 0) {
+                       return EINVAL;
+               }
+
+               if (uap->len < sizeof(notification)) {
+                       return EINVAL;
+               }
+
+               /*
+                * No privilege check, we assume a previous WORK_INTERVAL_OPERATION_CREATE
+                * operation would have allocated a work interval ID for the current
+                * thread, which the scheduler will validate.
+                */
+               if ((error = copyin(uap->arg, &notification, sizeof(notification)))) {
+                       return error;
+               }
+
+               struct kern_work_interval_args kwi_args = {
+                       .work_interval_id   = uap->work_interval_id,
+                       .start              = notification.start,
+                       .finish             = notification.finish,
+                       .deadline           = notification.deadline,
+                       .next_start         = notification.next_start,
+                       .notify_flags       = notification.notify_flags,
+                       .create_flags       = notification.create_flags,
+               };
+
+               kret = kern_work_interval_notify(current_thread(), &kwi_args);
+               if (kret != KERN_SUCCESS) {
+                       return EINVAL;
+               }
+
+               break;
+       case WORK_INTERVAL_OPERATION_JOIN:
+               if (uap->arg != USER_ADDR_NULL) {
+                       return EINVAL;
+               }
+
+               /*
+                * No privilege check, because the work interval port
+                * is a capability.
+                */
+               kret = kern_work_interval_join(current_thread(),
+                   (mach_port_name_t)uap->work_interval_id);
+               if (kret != KERN_SUCCESS) {
+                       return EINVAL;
+               }
+
+               break;
+
+       default:
+               return ENOTSUP;
        }
 
-       return (error);
+       return error;
 }
-