File:  [Qemu by Fabrice Bellard] / qemu / osdep.c
Revision 1.1.1.11 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 18:56:26 2018 UTC (3 years, 1 month ago) by root
Branches: qemu, MAIN
CVS tags: qemu1001, qemu1000, qemu0151, HEAD
qemu 0.15.1

    1: /*
    2:  * QEMU low level functions
    3:  *
    4:  * Copyright (c) 2003 Fabrice Bellard
    5:  *
    6:  * Permission is hereby granted, free of charge, to any person obtaining a copy
    7:  * of this software and associated documentation files (the "Software"), to deal
    8:  * in the Software without restriction, including without limitation the rights
    9:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   10:  * copies of the Software, and to permit persons to whom the Software is
   11:  * furnished to do so, subject to the following conditions:
   12:  *
   13:  * The above copyright notice and this permission notice shall be included in
   14:  * all copies or substantial portions of the Software.
   15:  *
   16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   17:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   21:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   22:  * THE SOFTWARE.
   23:  */
   24: #include <stdlib.h>
   25: #include <stdio.h>
   26: #include <stdarg.h>
   27: #include <string.h>
   28: #include <errno.h>
   29: #include <unistd.h>
   30: #include <fcntl.h>
   31: 
   32: /* Needed early for CONFIG_BSD etc. */
   33: #include "config-host.h"
   34: 
   35: #if defined(CONFIG_MADVISE) || defined(CONFIG_POSIX_MADVISE)
   36: #include <sys/mman.h>
   37: #endif
   38: 
   39: #ifdef CONFIG_SOLARIS
   40: #include <sys/types.h>
   41: #include <sys/statvfs.h>
   42: /* See MySQL bug #7156 (http://bugs.mysql.com/bug.php?id=7156) for
   43:    discussion about Solaris header problems */
   44: extern int madvise(caddr_t, size_t, int);
   45: #endif
   46: 
   47: #include "qemu-common.h"
   48: #include "trace.h"
   49: #include "qemu_socket.h"
   50: 
   51: int qemu_madvise(void *addr, size_t len, int advice)
   52: {
   53:     if (advice == QEMU_MADV_INVALID) {
   54:         errno = EINVAL;
   55:         return -1;
   56:     }
   57: #if defined(CONFIG_MADVISE)
   58:     return madvise(addr, len, advice);
   59: #elif defined(CONFIG_POSIX_MADVISE)
   60:     return posix_madvise(addr, len, advice);
   61: #else
   62:     errno = EINVAL;
   63:     return -1;
   64: #endif
   65: }
   66: 
   67: 
   68: /*
   69:  * Opens a file with FD_CLOEXEC set
   70:  */
   71: int qemu_open(const char *name, int flags, ...)
   72: {
   73:     int ret;
   74:     int mode = 0;
   75: 
   76:     if (flags & O_CREAT) {
   77:         va_list ap;
   78: 
   79:         va_start(ap, flags);
   80:         mode = va_arg(ap, int);
   81:         va_end(ap);
   82:     }
   83: 
   84: #ifdef O_CLOEXEC
   85:     ret = open(name, flags | O_CLOEXEC, mode);
   86: #else
   87:     ret = open(name, flags, mode);
   88:     if (ret >= 0) {
   89:         qemu_set_cloexec(ret);
   90:     }
   91: #endif
   92: 
   93:     return ret;
   94: }
   95: 
   96: /*
   97:  * A variant of write(2) which handles partial write.
   98:  *
   99:  * Return the number of bytes transferred.
  100:  * Set errno if fewer than `count' bytes are written.
  101:  *
  102:  * This function don't work with non-blocking fd's.
  103:  * Any of the possibilities with non-bloking fd's is bad:
  104:  *   - return a short write (then name is wrong)
  105:  *   - busy wait adding (errno == EAGAIN) to the loop
  106:  */
  107: ssize_t qemu_write_full(int fd, const void *buf, size_t count)
  108: {
  109:     ssize_t ret = 0;
  110:     ssize_t total = 0;
  111: 
  112:     while (count) {
  113:         ret = write(fd, buf, count);
  114:         if (ret < 0) {
  115:             if (errno == EINTR)
  116:                 continue;
  117:             break;
  118:         }
  119: 
  120:         count -= ret;
  121:         buf += ret;
  122:         total += ret;
  123:     }
  124: 
  125:     return total;
  126: }
  127: 
  128: /*
  129:  * Opens a socket with FD_CLOEXEC set
  130:  */
  131: int qemu_socket(int domain, int type, int protocol)
  132: {
  133:     int ret;
  134: 
  135: #ifdef SOCK_CLOEXEC
  136:     ret = socket(domain, type | SOCK_CLOEXEC, protocol);
  137:     if (ret != -1 || errno != EINVAL) {
  138:         return ret;
  139:     }
  140: #endif
  141:     ret = socket(domain, type, protocol);
  142:     if (ret >= 0) {
  143:         qemu_set_cloexec(ret);
  144:     }
  145: 
  146:     return ret;
  147: }
  148: 
  149: /*
  150:  * Accept a connection and set FD_CLOEXEC
  151:  */
  152: int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
  153: {
  154:     int ret;
  155: 
  156: #ifdef CONFIG_ACCEPT4
  157:     ret = accept4(s, addr, addrlen, SOCK_CLOEXEC);
  158:     if (ret != -1 || errno != ENOSYS) {
  159:         return ret;
  160:     }
  161: #endif
  162:     ret = accept(s, addr, addrlen);
  163:     if (ret >= 0) {
  164:         qemu_set_cloexec(ret);
  165:     }
  166: 
  167:     return ret;
  168: }

unix.superglobalmegacorp.com