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;
int eflag;
struct _client_info cinfo;
int tmp;
// get client info
if (sts = iofunc_client_info (ctp, 0, &cinfo)) {
return (sts);
}
// get parent and target
if (connect_msg_to_attr (ctp, &msg -> connect, handle,
&parent, &target, &sts, &cinfo)) {
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: