return(-ENOSYS);
}
-int sys_setsockopt(int sockfd, int level, int optname,
+int sys_setsockopt(int procfd, int level, int optname,
const void *optval, socklen_t optlen)
{
- return(-ENOSYS);
+ process_t *cproc;
+ int sockfd;
+ int ret_val;
+
+ if(level != SOL_SOCKET) {
+ ret_val = -EINVAL;
+ goto gtfo;
+ }
+
+ ret_val = -EFAULT;
+ cproc = process_get_current();
+
+ if(cproc) {
+ sockfd = process_flookup(cproc, procfd);
+
+ if(sockfd < 0) {
+ ret_val = sockfd;
+ } else {
+ char koptbuf[128];
+ socklen_t koptlen;
+
+ /*
+ * The memory referenced by `optval' is in the process's
+ * address space, so we have to copy it into the kernel's
+ * address space before being able to use it. Since the
+ * process's buffer may sit on the boundary of two non-
+ * consecutive pages, we can't just use the linear
+ * address.
+ */
+
+ koptlen = optlen < sizeof(koptbuf) ? optlen : sizeof(koptbuf);
+ process_memcpy_ptok(cproc, koptbuf, (void*)optval, koptlen);
+
+ ret_val = sosetopt(sockfd, optname, koptbuf, koptlen);
+ }
+ }
+
+gtfo:
+ return(ret_val);
}
-int sys_getsockopt(int sockfd, int level, int optname,
+int sys_getsockopt(int procfd, int level, int optname,
void *optval, socklen_t *optlen)
{
- return(-ENOSYS);
+ process_t *cproc;
+ int sockfd;
+ int ret_val;
+
+ /*
+ * This function is essentially the same as sys_setsockopt(), except that it
+ * calls sogetopt() instead of sosetopt(), and the buffer is copied after that
+ * call, in the opposite direction.
+ */
+
+ if(level != SOL_SOCKET) {
+ ret_val = -EINVAL;
+ goto gtfo;
+ }
+
+ ret_val = -EFAULT;
+ cproc = process_get_current();
+
+ if(cproc) {
+ sockfd = process_flookup(cproc, procfd);
+
+ if(sockfd < 0) {
+ ret_val = sockfd;
+ } else {
+ char koptbuf[128];
+ socklen_t koptlen;
+
+ koptlen = *optlen < sizeof(koptbuf) ? *optlen : sizeof(koptbuf);
+
+ ret_val = sogetopt(sockfd, optname, koptbuf, &koptlen);
+
+ if(!ret_val) {
+ /* return data to user-space if the call was successful */
+
+ process_memcpy_ktop(cproc, optval, koptbuf, koptlen);
+ /* as annoying (and unlikely) as it may be, optlen may also sit on a page-boundary */
+ process_memcpy_ktop(cproc, optlen, &koptlen, sizeof(koptlen));
+ }
+ }
+ }
+
+gtfo:
+ return(ret_val);
}
int sys_shutdown(int sockfd, int how)