Finally, the c_open() code walkthrough

Now that we understand all of the steps involved in processing the c_open() (and, coincidentally, large chunks of all other connect functions), it's time to look at the code.

int
cfs_c_open (resmgr_context_t *ctp, io_open_t *msg,
            RESMGR_HANDLE_T *handle, void *extra)
{
  int       sts;
  des_t     parent, target;
  struct    _client_info *cinfo = NULL;

  // 1) fetch the client information
  if ((sts = iofunc_client_info_ext (ctp, 0, &cinfo, IOFUNC_CLIENTINFO_GETGROUPS)) != EOK) {  
    return (sts);
  }

  // 2) call the helper connect_msg_to_attr
  if (connect_msg_to_attr (ctp, &msg -> connect, handle,
                           &parent, &target, &sts, cinfo)) {
    (void)iofunc_client_info_ext_free (&cinfo);
    return (sts);
  }

  // if the target doesn't exist
  if (!target.attr) {
    // 3) and we're not creating it, error
    if (!(msg -> connect.ioflag & O_CREAT)) {
      (void)iofunc_client_info_ext_free (&cinfo);
      return (ENOENT);
    }

    // 4) else we are creating it, call the helper iofunc_open
    sts = iofunc_open (ctp, msg, NULL, &parent.attr -> attr, NULL);
    if (sts != EOK) {
      (void)iofunc_client_info_ext_free (&cinfo);
      return (sts);
    }

    // 5) create an attributes structure for the new entry
    target.attr = cfs_a_mkfile (parent.attr, target.name, cinfo);
    (void)iofunc_client_info_ext_free (&cinfo);
    if (!target.attr) {
      return (errno);
    }

  // else the target exists
  } else {
    // 6) call the helper function iofunc_open
    sts = iofunc_open (ctp, msg, &target.attr -> attr,
                       NULL, NULL);
    if (sts != EOK) {
      return (sts);
    }
  }

  // 7) Target existed or just created, truncate if required.
  if (msg -> connect.ioflag & O_TRUNC) {
    // truncate at offset zero because we're opening it:
    cfs_a_truncate (target.attr, 0, TRUNCATE_ERASE);
  }

  // 8) bind the OCB and attributes structures
  sts = iofunc_ocb_attach (ctp, msg, NULL,
                           &target.attr -> attr, NULL);

  return (sts);
}