int (*rename) ( resmgr_context_t *ctp, io_rename_t *msg, RESMGR_HANDLE_T *handle, io_rename_extra_t *extra )
struct _io_connect { // internal fields (as described above) uint16_t path_len; uint8_t extra_type; uint16_t extra_len; char path [1]; }; struct _io_connect_link_reply { uint32_t reserved1; uint32_t file_type; uint8_t eflag; uint8_t reserved2[1]; uint16_t chroot_len; uint32_t umask; uint16_t nentries; uint16_t path_len; }; struct _io_connect_ftype_reply { uint16_t status; /* Typically an errno */ uint16_t reserved; uint32_t file_type; /* _FTYPE_? in sys/ftype.h */ }; typedef union _io_rename_extra { char path [1]; } io_rename_extra_t; typedef union { struct _io_connect connect; struct _io_connect_link_reply link_reply; struct _io_connect_ftype_reply ftype_reply; } io_rename_t;
This function will be called only with two filenames that are on the same filesystem (same device). Therefore, there's no need to check for a case where you'd return EXDEV. This doesn't prevent you from returning EXDEV if you don't wish to perform the rename() yourself (for example, it may be very complicated to do the rename operation from one directory to another). In the case of returning EXDEV, the shell utility mv will perform a cp followed by an rm (the C library function rename() will do no such thing—it will return only an errno of EXDEV).
Also, all symlinks will be resolved, where applicable, before this function is called, and the pathnames passed will be absolute and rooted in the filesystem for which this resource manager is responsible.
The default iofunc_rename() function relies on permission checking in iofunc_link() and iofunc_unlink().