int inode_stat(FAR struct inode *inode, FAR struct stat *buf) { DEBUGASSERT(inode != NULL && buf != NULL); memset(buf, 0, sizeof(*buf)); if (INODE_IS_SPECIAL(inode)) { #if defined(CONFIG_FS_NAMED_SEMAPHORES) if (INODE_IS_NAMEDSEM(inode)) { buf->st_mode = S_IFSEM; } else #endif #if !defined(CONFIG_DISABLE_MQUEUE) if (INODE_IS_MQUEUE(inode)) { buf->st_mode = S_IFMQ; } else #endif { } } else if (inode->u.i_ops != NULL) { /* Determine read/write privileges based on the existence of read * and write methods. */ if (inode->u.i_ops->read) { buf->st_mode = S_IROTH | S_IRGRP | S_IRUSR; } if (inode->u.i_ops->write) { buf->st_mode |= S_IWOTH | S_IWGRP | S_IWUSR; } /* Determine the type of the inode */ if (INODE_IS_MOUNTPT(inode)) { buf->st_mode |= S_IFDIR; } else if (INODE_IS_BLOCK(inode)) { /* What is if also has child inodes? */ buf->st_mode |= S_IFBLK; } else /* if (INODE_IS_DRIVER(inode)) */ { /* What is it if it also has child inodes? */ buf->st_mode |= S_IFCHR; } } else { /* If it has no operations, then it must just be a intermediate * node in the inode tree. It is something like a directory. * We'll say that all pseudo-directories are read-able but not * write-able. */ buf->st_mode |= S_IFDIR | S_IROTH | S_IRGRP | S_IRUSR; } return OK; }
int sem_unlink(FAR const char *name) { FAR struct inode *inode; FAR const char *relpath = NULL; char fullpath[MAX_SEMPATH]; int errcode; int ret; /* Get the full path to the semaphore */ snprintf(fullpath, MAX_SEMPATH, CONFIG_FS_NAMED_SEMPATH "/%s", name); /* Get the inode for this semaphore. */ sched_lock(); inode = inode_find(fullpath, &relpath); if (!inode) { /* There is no inode that includes in this path */ errcode = ENOENT; goto errout; } /* Verify that what we found is, indeed, a semaphore */ if (!INODE_IS_NAMEDSEM(inode)) { errcode = ENXIO; goto errout_with_inode; } /* Refuse to unlink the inode if it has children. I.e., if it is * functioning as a directory and the directory is not empty. */ inode_semtake(); if (inode->i_child != NULL) { errcode = ENOTEMPTY; goto errout_with_semaphore; } /* Remove the old inode from the tree. Because we hold a reference count * on the inode, it will not be deleted now. This will set the * FSNODEFLAG_DELETED bit in the inode flags. */ ret = inode_remove(fullpath); /* inode_remove() should always fail with -EBUSY because we hae a reference * on the inode. -EBUSY means taht the inode was, indeed, unlinked but * thatis could not be freed because there are refrences. */ DEBUGASSERT(ret >= 0 || ret == -EBUSY); UNUSED(ret); /* Now we do not release the reference count in the normal way (by calling * inode release. Rather, we call sem_close(). sem_close will decrement * the reference count on the inode. But it will also free the semaphore * if that reference count decrements to zero. Since we hold one reference, * that can only occur if the semaphore is not in-use. */ inode_semgive(); ret = sem_close((FAR sem_t *)inode->u.i_nsem); sched_unlock(); return ret; errout_with_semaphore: inode_semgive(); errout_with_inode: inode_release(inode); errout: set_errno(errcode); sched_unlock(); return ERROR; }