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); }