linux-user: Implement accept4
Implement the accept4 syscall (which is identical to accept but has an additional flags argument). Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
This commit is contained in:
		
							parent
							
								
									a8fd1aba85
								
							
						
					
					
						commit
						a94b4987e2
					
				| @ -2004,16 +2004,30 @@ out2: | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| /* do_accept() Must return target values and target errnos. */ | ||||
| static abi_long do_accept(int fd, abi_ulong target_addr, | ||||
|                           abi_ulong target_addrlen_addr) | ||||
| /* If we don't have a system accept4() then just call accept.
 | ||||
|  * The callsites to do_accept4() will ensure that they don't | ||||
|  * pass a non-zero flags argument in this config. | ||||
|  */ | ||||
| #ifndef CONFIG_ACCEPT4 | ||||
| static inline int accept4(int sockfd, struct sockaddr *addr, | ||||
|                           socklen_t *addrlen, int flags) | ||||
| { | ||||
|     assert(flags == 0); | ||||
|     return accept(sockfd, addr, addrlen); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| /* do_accept4() Must return target values and target errnos. */ | ||||
| static abi_long do_accept4(int fd, abi_ulong target_addr, | ||||
|                            abi_ulong target_addrlen_addr, int flags) | ||||
| { | ||||
|     socklen_t addrlen; | ||||
|     void *addr; | ||||
|     abi_long ret; | ||||
| 
 | ||||
|     if (target_addr == 0) | ||||
|        return get_errno(accept(fd, NULL, NULL)); | ||||
|     if (target_addr == 0) { | ||||
|         return get_errno(accept4(fd, NULL, NULL, flags)); | ||||
|     } | ||||
| 
 | ||||
|     /* linux returns EINVAL if addrlen pointer is invalid */ | ||||
|     if (get_user_u32(addrlen, target_addrlen_addr)) | ||||
| @ -2028,7 +2042,7 @@ static abi_long do_accept(int fd, abi_ulong target_addr, | ||||
| 
 | ||||
|     addr = alloca(addrlen); | ||||
| 
 | ||||
|     ret = get_errno(accept(fd, addr, &addrlen)); | ||||
|     ret = get_errno(accept4(fd, addr, &addrlen, flags)); | ||||
|     if (!is_error(ret)) { | ||||
|         host_to_target_sockaddr(target_addr, addr, addrlen); | ||||
|         if (put_user_u32(addrlen, target_addrlen_addr)) | ||||
| @ -2254,7 +2268,7 @@ static abi_long do_socketcall(int num, abi_ulong vptr) | ||||
|                 || get_user_ual(target_addrlen, vptr + 2 * n)) | ||||
|                 return -TARGET_EFAULT; | ||||
| 
 | ||||
|             ret = do_accept(sockfd, target_addr, target_addrlen); | ||||
|             ret = do_accept4(sockfd, target_addr, target_addrlen, 0); | ||||
|         } | ||||
|         break; | ||||
|     case SOCKOP_getsockname: | ||||
| @ -6677,7 +6691,16 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||||
| #endif | ||||
| #ifdef TARGET_NR_accept | ||||
|     case TARGET_NR_accept: | ||||
|         ret = do_accept(arg1, arg2, arg3); | ||||
|         ret = do_accept4(arg1, arg2, arg3, 0); | ||||
|         break; | ||||
| #endif | ||||
| #ifdef TARGET_NR_accept4 | ||||
|     case TARGET_NR_accept4: | ||||
| #ifdef CONFIG_ACCEPT4 | ||||
|         ret = do_accept4(arg1, arg2, arg3, arg4); | ||||
| #else | ||||
|         goto unimplemented; | ||||
| #endif | ||||
|         break; | ||||
| #endif | ||||
| #ifdef TARGET_NR_bind | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Peter Maydell
						Peter Maydell