The c_readlink() function
This is a simple one. You've already seen how symlinks are stored internally in the RAM-disk resource manager. The job of c_readlink() is to return the value of the symbolic link. It's called when you do a full ls, for example:
# ls -lF /my_temp
lrwxrwxrwx 1 root root 4 Aug 16 14:06 /my_temp@ -> /tmp
Since this code shares a lot in common with the processing for c_open(), I'll just point out the major differences.
int
cfs_c_readlink (resmgr_context_t *ctp, io_readlink_t *msg,
RESMGR_HANDLE_T *handle, void *reserved)
{
des_t parent, target;
int sts, sts2;
int eflag;
struct _client_info *cinfo;
int tmp;
// get client info
if ((sts = iofunc_client_info_ext (ctp, 0, &cinfo, IOFUNC_CLIENTINFO_GETGROUPS)) != EOK) {
return (sts);
}
// get parent and target
sts2 = connect_msg_to_attr (ctp, &msg -> connect, handle,
&parent, &target, &sts, cinfo);
(void)iofunc_client_info_ext_free (&cinfo);
if (sts2 != EOK) {
return (sts);
}
// there has to be a target!
if (!target.attr) {
return (sts);
}
// 1) call the helper function
sts = iofunc_readlink (ctp, msg, &target.attr -> attr, NULL);
if (sts != EOK) {
return (sts);
}
// 2) preserve eflag...
eflag = msg -> connect.eflag;
memset (&msg -> link_reply, 0, sizeof (msg -> link_reply));
msg -> link_reply.eflag = eflag;
// 3) return data
tmp = strlen (target.attr -> type.symlinkdata);
SETIOV (&ctp -> iov [0], &msg -> link_reply,
sizeof (msg -> link_reply));
SETIOV (&ctp -> iov[1], target.attr -> type.symlinkdata, tmp);
msg -> link_reply.path_len = tmp;
MsgReplyv (ctp -> rcvid, EOK, ctp -> iov, 2);
return (_RESMGR_NOREPLY);
}
The detailed code walkthrough is as follows:
- We use the helper function iofunc_readlink() to do basic checking for us. If it's not happy with the parameters, then we return whatever it returned.
- Just like in symlink redirection, we need to preserve flags; in this case it's just the eflag—we zero-out everything else.
- And, just as in the symlink redirection, we return a two-part IOV; the first part points to the header, the second part points to the string. Note that in this case, unlike symlink redirection, we didn't need to construct the pathname. That's because the goal of this function is to return just the contents of the symlink, and we know that they're sitting in the symlinkdata member of the extended attributes structure.
Page updated:
