Annotation of OSKit-Mach/ipc/mach_debug.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Mach Operating System
        !             3:  * Copyright (c) 1991,1990 Carnegie Mellon University
        !             4:  * All Rights Reserved.
        !             5:  *
        !             6:  * Permission to use, copy, modify and distribute this software and its
        !             7:  * documentation is hereby granted, provided that both the copyright
        !             8:  * notice and this permission notice appear in all copies of the
        !             9:  * software, derivative works or modified versions, and any portions
        !            10:  * thereof, and that both notices appear in supporting documentation.
        !            11:  *
        !            12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !            13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
        !            14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            15:  *
        !            16:  * Carnegie Mellon requests users of this software to return to
        !            17:  *
        !            18:  *  Software Distribution Coordinator  or  [email protected]
        !            19:  *  School of Computer Science
        !            20:  *  Carnegie Mellon University
        !            21:  *  Pittsburgh PA 15213-3890
        !            22:  *
        !            23:  * any improvements or extensions that they make and grant Carnegie Mellon
        !            24:  * the rights to redistribute these changes.
        !            25:  */
        !            26: /*
        !            27:  */
        !            28: /*
        !            29:  *     File:   ipc/mach_debug.c
        !            30:  *     Author: Rich Draves
        !            31:  *     Date:   1989
        !            32:  *
        !            33:  *     Exported kernel calls.  See mach_debug/mach_debug.defs.
        !            34:  */
        !            35: 
        !            36: #include <mach_ipc_compat.h>
        !            37: 
        !            38: #include <mach/kern_return.h>
        !            39: #include <mach/port.h>
        !            40: #include <mach/machine/vm_types.h>
        !            41: #include <mach/vm_param.h>
        !            42: #include <mach_debug/ipc_info.h>
        !            43: #include <mach_debug/hash_info.h>
        !            44: #include <kern/host.h>
        !            45: #include <vm/vm_map.h>
        !            46: #include <vm/vm_kern.h>
        !            47: #include <ipc/ipc_space.h>
        !            48: #include <ipc/ipc_port.h>
        !            49: #include <ipc/ipc_hash.h>
        !            50: #include <ipc/ipc_marequest.h>
        !            51: #include <ipc/ipc_table.h>
        !            52: #include <ipc/ipc_right.h>
        !            53: 
        !            54: 
        !            55: 
        !            56: /*
        !            57:  *     Routine:        mach_port_get_srights [kernel call]
        !            58:  *     Purpose:
        !            59:  *             Retrieve the number of extant send rights
        !            60:  *             that a receive right has.
        !            61:  *     Conditions:
        !            62:  *             Nothing locked.
        !            63:  *     Returns:
        !            64:  *             KERN_SUCCESS            Retrieved number of send rights.
        !            65:  *             KERN_INVALID_TASK       The space is null.
        !            66:  *             KERN_INVALID_TASK       The space is dead.
        !            67:  *             KERN_INVALID_NAME       The name doesn't denote a right.
        !            68:  *             KERN_INVALID_RIGHT      Name doesn't denote receive rights.
        !            69:  */
        !            70: 
        !            71: kern_return_t
        !            72: mach_port_get_srights(
        !            73:        ipc_space_t             space,
        !            74:        mach_port_t             name,
        !            75:        mach_port_rights_t      *srightsp)
        !            76: {
        !            77:        ipc_port_t port;
        !            78:        kern_return_t kr;
        !            79:        mach_port_rights_t srights;
        !            80: 
        !            81:        if (space == IS_NULL)
        !            82:                return KERN_INVALID_TASK;
        !            83: 
        !            84:        kr = ipc_port_translate_receive(space, name, &port);
        !            85:        if (kr != KERN_SUCCESS)
        !            86:                return kr;
        !            87:        /* port is locked and active */
        !            88: 
        !            89:        srights = port->ip_srights;
        !            90:        ip_unlock(port);
        !            91: 
        !            92:        *srightsp = srights;
        !            93:        return KERN_SUCCESS;
        !            94: }
        !            95: 
        !            96: /*
        !            97:  *     Routine:        host_ipc_hash_info
        !            98:  *     Purpose:
        !            99:  *             Return information about the global reverse hash table.
        !           100:  *     Conditions:
        !           101:  *             Nothing locked.  Obeys CountInOut protocol.
        !           102:  *     Returns:
        !           103:  *             KERN_SUCCESS            Returned information.
        !           104:  *             KERN_INVALID_HOST       The host is null.
        !           105:  *             KERN_RESOURCE_SHORTAGE  Couldn't allocate memory.
        !           106:  */
        !           107: 
        !           108: kern_return_t
        !           109: host_ipc_hash_info(
        !           110:        host_t                          host,
        !           111:        hash_info_bucket_array_t        *infop,
        !           112:        mach_msg_type_number_t          *countp)
        !           113: {
        !           114:        vm_offset_t addr;
        !           115:        vm_size_t size;
        !           116:        hash_info_bucket_t *info;
        !           117:        unsigned int potential, actual;
        !           118:        kern_return_t kr;
        !           119: 
        !           120:        if (host == HOST_NULL)
        !           121:                return KERN_INVALID_HOST;
        !           122: 
        !           123:        /* start with in-line data */
        !           124: 
        !           125:        info = *infop;
        !           126:        potential = *countp;
        !           127: 
        !           128:        for (;;) {
        !           129:                actual = ipc_hash_info(info, potential);
        !           130:                if (actual <= potential)
        !           131:                        break;
        !           132: 
        !           133:                /* allocate more memory */
        !           134: 
        !           135:                if (info != *infop)
        !           136:                        kmem_free(ipc_kernel_map, addr, size);
        !           137: 
        !           138:                size = round_page(actual * sizeof *info);
        !           139:                kr = kmem_alloc_pageable(ipc_kernel_map, &addr, size);
        !           140:                if (kr != KERN_SUCCESS)
        !           141:                        return KERN_RESOURCE_SHORTAGE;
        !           142: 
        !           143:                info = (hash_info_bucket_t *) addr;
        !           144:                potential = size/sizeof *info;
        !           145:        }
        !           146: 
        !           147:        if (info == *infop) {
        !           148:                /* data fit in-line; nothing to deallocate */
        !           149: 
        !           150:                *countp = actual;
        !           151:        } else if (actual == 0) {
        !           152:                kmem_free(ipc_kernel_map, addr, size);
        !           153: 
        !           154:                *countp = 0;
        !           155:        } else {
        !           156:                vm_map_copy_t copy;
        !           157:                vm_size_t used;
        !           158: 
        !           159:                used = round_page(actual * sizeof *info);
        !           160: 
        !           161:                if (used != size)
        !           162:                        kmem_free(ipc_kernel_map, addr + used, size - used);
        !           163: 
        !           164:                kr = vm_map_copyin(ipc_kernel_map, addr, used,
        !           165:                                   TRUE, &copy);
        !           166:                assert(kr == KERN_SUCCESS);
        !           167: 
        !           168:                *infop = (hash_info_bucket_t *) copy;
        !           169:                *countp = actual;
        !           170:        }
        !           171: 
        !           172:        return KERN_SUCCESS;
        !           173: }
        !           174: 
        !           175: /*
        !           176:  *     Routine:        host_ipc_marequest_info
        !           177:  *     Purpose:
        !           178:  *             Return information about the marequest hash table.
        !           179:  *     Conditions:
        !           180:  *             Nothing locked.  Obeys CountInOut protocol.
        !           181:  *     Returns:
        !           182:  *             KERN_SUCCESS            Returned information.
        !           183:  *             KERN_INVALID_HOST       The host is null.
        !           184:  *             KERN_RESOURCE_SHORTAGE  Couldn't allocate memory.
        !           185:  */
        !           186: 
        !           187: kern_return_t
        !           188: host_ipc_marequest_info(host, maxp, infop, countp)
        !           189:        host_t host;
        !           190:        unsigned int *maxp;
        !           191:        hash_info_bucket_array_t *infop;
        !           192:        unsigned int *countp;
        !           193: {
        !           194:        vm_offset_t addr;
        !           195:        vm_size_t size = 0; /* '=0' to shut up lint */
        !           196:        hash_info_bucket_t *info;
        !           197:        unsigned int potential, actual;
        !           198:        kern_return_t kr;
        !           199: 
        !           200:        if (host == HOST_NULL)
        !           201:                return KERN_INVALID_HOST;
        !           202: 
        !           203:        /* start with in-line data */
        !           204: 
        !           205:        info = *infop;
        !           206:        potential = *countp;
        !           207: 
        !           208:        for (;;) {
        !           209:                actual = ipc_marequest_info(maxp, info, potential);
        !           210:                if (actual <= potential)
        !           211:                        break;
        !           212: 
        !           213:                /* allocate more memory */
        !           214: 
        !           215:                if (info != *infop)
        !           216:                        kmem_free(ipc_kernel_map, addr, size);
        !           217: 
        !           218:                size = round_page(actual * sizeof *info);
        !           219:                kr = kmem_alloc_pageable(ipc_kernel_map, &addr, size);
        !           220:                if (kr != KERN_SUCCESS)
        !           221:                        return KERN_RESOURCE_SHORTAGE;
        !           222: 
        !           223:                info = (hash_info_bucket_t *) addr;
        !           224:                potential = size/sizeof *info;
        !           225:        }
        !           226: 
        !           227:        if (info == *infop) {
        !           228:                /* data fit in-line; nothing to deallocate */
        !           229: 
        !           230:                *countp = actual;
        !           231:        } else if (actual == 0) {
        !           232:                kmem_free(ipc_kernel_map, addr, size);
        !           233: 
        !           234:                *countp = 0;
        !           235:        } else {
        !           236:                vm_map_copy_t copy;
        !           237:                vm_size_t used;
        !           238: 
        !           239:                used = round_page(actual * sizeof *info);
        !           240: 
        !           241:                if (used != size)
        !           242:                        kmem_free(ipc_kernel_map, addr + used, size - used);
        !           243: 
        !           244:                kr = vm_map_copyin(ipc_kernel_map, addr, used,
        !           245:                                   TRUE, &copy);
        !           246:                assert(kr == KERN_SUCCESS);
        !           247: 
        !           248:                *infop = (hash_info_bucket_t *) copy;
        !           249:                *countp = actual;
        !           250:        }
        !           251: 
        !           252:        return KERN_SUCCESS;
        !           253: }
        !           254: 
        !           255: /*
        !           256:  *     Routine:        mach_port_space_info
        !           257:  *     Purpose:
        !           258:  *             Returns information about an IPC space.
        !           259:  *     Conditions:
        !           260:  *             Nothing locked.  Obeys CountInOut protocol.
        !           261:  *     Returns:
        !           262:  *             KERN_SUCCESS            Returned information.
        !           263:  *             KERN_INVALID_TASK       The space is null.
        !           264:  *             KERN_INVALID_TASK       The space is dead.
        !           265:  *             KERN_RESOURCE_SHORTAGE  Couldn't allocate memory.
        !           266:  */
        !           267: 
        !           268: kern_return_t
        !           269: mach_port_space_info(
        !           270:        ipc_space_t                     space,
        !           271:        ipc_info_space_t                *infop,
        !           272:        ipc_info_name_array_t           *tablep,
        !           273:        mach_msg_type_number_t          *tableCntp,
        !           274:        ipc_info_tree_name_array_t      *treep,
        !           275:        mach_msg_type_number_t          *treeCntp)
        !           276: {
        !           277:        ipc_info_name_t *table_info;
        !           278:        unsigned int table_potential, table_actual;
        !           279:        vm_offset_t table_addr;
        !           280:        vm_size_t table_size;
        !           281:        ipc_info_tree_name_t *tree_info;
        !           282:        unsigned int tree_potential, tree_actual;
        !           283:        vm_offset_t tree_addr;
        !           284:        vm_size_t tree_size;
        !           285:        ipc_tree_entry_t tentry;
        !           286:        ipc_entry_t table;
        !           287:        ipc_entry_num_t tsize;
        !           288:        mach_port_index_t index;
        !           289:        kern_return_t kr;
        !           290: 
        !           291:        if (space == IS_NULL)
        !           292:                return KERN_INVALID_TASK;
        !           293: 
        !           294:        /* start with in-line memory */
        !           295: 
        !           296:        table_info = *tablep;
        !           297:        table_potential = *tableCntp;
        !           298:        tree_info = *treep;
        !           299:        tree_potential = *treeCntp;
        !           300: 
        !           301:        for (;;) {
        !           302:                is_read_lock(space);
        !           303:                if (!space->is_active) {
        !           304:                        is_read_unlock(space);
        !           305:                        if (table_info != *tablep)
        !           306:                                kmem_free(ipc_kernel_map,
        !           307:                                          table_addr, table_size);
        !           308:                        if (tree_info != *treep)
        !           309:                                kmem_free(ipc_kernel_map,
        !           310:                                          tree_addr, tree_size);
        !           311:                        return KERN_INVALID_TASK;
        !           312:                }
        !           313: 
        !           314:                table_actual = space->is_table_size;
        !           315:                tree_actual = space->is_tree_total;
        !           316: 
        !           317:                if ((table_actual <= table_potential) &&
        !           318:                    (tree_actual <= tree_potential))
        !           319:                        break;
        !           320: 
        !           321:                is_read_unlock(space);
        !           322: 
        !           323:                if (table_actual > table_potential) {
        !           324:                        if (table_info != *tablep)
        !           325:                                kmem_free(ipc_kernel_map,
        !           326:                                          table_addr, table_size);
        !           327: 
        !           328:                        table_size = round_page(table_actual *
        !           329:                                                sizeof *table_info);
        !           330:                        kr = kmem_alloc(ipc_kernel_map,
        !           331:                                        &table_addr, table_size);
        !           332:                        if (kr != KERN_SUCCESS) {
        !           333:                                if (tree_info != *treep)
        !           334:                                        kmem_free(ipc_kernel_map,
        !           335:                                                  tree_addr, tree_size);
        !           336: 
        !           337:                                return KERN_RESOURCE_SHORTAGE;
        !           338:                        }
        !           339: 
        !           340:                        table_info = (ipc_info_name_t *) table_addr;
        !           341:                        table_potential = table_size/sizeof *table_info;
        !           342:                }
        !           343: 
        !           344:                if (tree_actual > tree_potential) {
        !           345:                        if (tree_info != *treep)
        !           346:                                kmem_free(ipc_kernel_map,
        !           347:                                          tree_addr, tree_size);
        !           348: 
        !           349:                        tree_size = round_page(tree_actual *
        !           350:                                               sizeof *tree_info);
        !           351:                        kr = kmem_alloc(ipc_kernel_map,
        !           352:                                        &tree_addr, tree_size);
        !           353:                        if (kr != KERN_SUCCESS) {
        !           354:                                if (table_info != *tablep)
        !           355:                                        kmem_free(ipc_kernel_map,
        !           356:                                                  table_addr, table_size);
        !           357: 
        !           358:                                return KERN_RESOURCE_SHORTAGE;
        !           359:                        }
        !           360: 
        !           361:                        tree_info = (ipc_info_tree_name_t *) tree_addr;
        !           362:                        tree_potential = tree_size/sizeof *tree_info;
        !           363:                }
        !           364:        }
        !           365:        /* space is read-locked and active; we have enough wired memory */
        !           366: 
        !           367:        infop->iis_genno_mask = MACH_PORT_NGEN(MACH_PORT_DEAD);
        !           368:        infop->iis_table_size = space->is_table_size;
        !           369:        infop->iis_table_next = space->is_table_next->its_size;
        !           370:        infop->iis_tree_size = space->is_tree_total;
        !           371:        infop->iis_tree_small = space->is_tree_small;
        !           372:        infop->iis_tree_hash = space->is_tree_hash;
        !           373: 
        !           374:        table = space->is_table;
        !           375:        tsize = space->is_table_size;
        !           376: 
        !           377:        for (index = 0; index < tsize; index++) {
        !           378:                ipc_info_name_t *iin = &table_info[index];
        !           379:                ipc_entry_t entry = &table[index];
        !           380:                ipc_entry_bits_t bits = entry->ie_bits;
        !           381: 
        !           382:                iin->iin_name = MACH_PORT_MAKEB(index, bits);
        !           383:                iin->iin_collision = (bits & IE_BITS_COLLISION) ? TRUE : FALSE;
        !           384: #if    MACH_IPC_COMPAT
        !           385:                iin->iin_compat = (bits & IE_BITS_COMPAT) ? TRUE : FALSE;
        !           386: #else  /* MACH_IPC_COMPAT */
        !           387:                iin->iin_compat = FALSE;
        !           388: #endif /* MACH_IPC_COMPAT */
        !           389:                iin->iin_marequest = (bits & IE_BITS_MAREQUEST) ? TRUE : FALSE;
        !           390:                iin->iin_type = IE_BITS_TYPE(bits);
        !           391:                iin->iin_urefs = IE_BITS_UREFS(bits);
        !           392:                iin->iin_object = (vm_offset_t) entry->ie_object;
        !           393:                iin->iin_next = entry->ie_next;
        !           394:                iin->iin_hash = entry->ie_index;
        !           395:        }
        !           396: 
        !           397:        for (tentry = ipc_splay_traverse_start(&space->is_tree), index = 0;
        !           398:             tentry != ITE_NULL;
        !           399:             tentry = ipc_splay_traverse_next(&space->is_tree, FALSE)) {
        !           400:                ipc_info_tree_name_t *iitn = &tree_info[index++];
        !           401:                ipc_info_name_t *iin = &iitn->iitn_name;
        !           402:                ipc_entry_t entry = &tentry->ite_entry;
        !           403:                ipc_entry_bits_t bits = entry->ie_bits;
        !           404: 
        !           405:                assert(IE_BITS_TYPE(bits) != MACH_PORT_TYPE_NONE);
        !           406: 
        !           407:                iin->iin_name = tentry->ite_name;
        !           408:                iin->iin_collision = (bits & IE_BITS_COLLISION) ? TRUE : FALSE;
        !           409: #if    MACH_IPC_COMPAT
        !           410:                iin->iin_compat = (bits & IE_BITS_COMPAT) ? TRUE : FALSE;
        !           411: #else  /* MACH_IPC_COMPAT */
        !           412:                iin->iin_compat = FALSE;
        !           413: #endif /* MACH_IPC_COMPAT */
        !           414:                iin->iin_marequest = (bits & IE_BITS_MAREQUEST) ? TRUE : FALSE;
        !           415:                iin->iin_type = IE_BITS_TYPE(bits);
        !           416:                iin->iin_urefs = IE_BITS_UREFS(bits);
        !           417:                iin->iin_object = (vm_offset_t) entry->ie_object;
        !           418:                iin->iin_next = entry->ie_next;
        !           419:                iin->iin_hash = entry->ie_index;
        !           420: 
        !           421:                if (tentry->ite_lchild == ITE_NULL)
        !           422:                        iitn->iitn_lchild = MACH_PORT_NULL;
        !           423:                else
        !           424:                        iitn->iitn_lchild = tentry->ite_lchild->ite_name;
        !           425: 
        !           426:                if (tentry->ite_rchild == ITE_NULL)
        !           427:                        iitn->iitn_rchild = MACH_PORT_NULL;
        !           428:                else
        !           429:                        iitn->iitn_rchild = tentry->ite_rchild->ite_name;
        !           430: 
        !           431:        }
        !           432:        ipc_splay_traverse_finish(&space->is_tree);
        !           433:        is_read_unlock(space);
        !           434: 
        !           435:        if (table_info == *tablep) {
        !           436:                /* data fit in-line; nothing to deallocate */
        !           437: 
        !           438:                *tableCntp = table_actual;
        !           439:        } else if (table_actual == 0) {
        !           440:                kmem_free(ipc_kernel_map, table_addr, table_size);
        !           441: 
        !           442:                *tableCntp = 0;
        !           443:        } else {
        !           444:                vm_size_t size_used, rsize_used;
        !           445:                vm_map_copy_t copy;
        !           446: 
        !           447:                /* kmem_alloc doesn't zero memory */
        !           448: 
        !           449:                size_used = table_actual * sizeof *table_info;
        !           450:                rsize_used = round_page(size_used);
        !           451: 
        !           452:                if (rsize_used != table_size)
        !           453:                        kmem_free(ipc_kernel_map,
        !           454:                                  table_addr + rsize_used,
        !           455:                                  table_size - rsize_used);
        !           456: 
        !           457:                if (size_used != rsize_used)
        !           458:                        bzero((char *) (table_addr + size_used),
        !           459:                              rsize_used - size_used);
        !           460: 
        !           461:                kr = vm_map_copyin(ipc_kernel_map, table_addr, rsize_used,
        !           462:                                   TRUE, &copy);
        !           463: 
        !           464:                assert(kr == KERN_SUCCESS);
        !           465: 
        !           466:                *tablep = (ipc_info_name_t *) copy;
        !           467:                *tableCntp = table_actual;
        !           468:        }
        !           469: 
        !           470:        if (tree_info == *treep) {
        !           471:                /* data fit in-line; nothing to deallocate */
        !           472: 
        !           473:                *treeCntp = tree_actual;
        !           474:        } else if (tree_actual == 0) {
        !           475:                kmem_free(ipc_kernel_map, tree_addr, tree_size);
        !           476: 
        !           477:                *treeCntp = 0;
        !           478:        } else {
        !           479:                vm_size_t size_used, rsize_used;
        !           480:                vm_map_copy_t copy;
        !           481: 
        !           482:                /* kmem_alloc doesn't zero memory */
        !           483: 
        !           484:                size_used = tree_actual * sizeof *tree_info;
        !           485:                rsize_used = round_page(size_used);
        !           486: 
        !           487:                if (rsize_used != tree_size)
        !           488:                        kmem_free(ipc_kernel_map,
        !           489:                                  tree_addr + rsize_used,
        !           490:                                  tree_size - rsize_used);
        !           491: 
        !           492:                if (size_used != rsize_used)
        !           493:                        bzero((char *) (tree_addr + size_used),
        !           494:                              rsize_used - size_used);
        !           495: 
        !           496:                kr = vm_map_copyin(ipc_kernel_map, tree_addr, rsize_used,
        !           497:                                   TRUE, &copy);
        !           498: 
        !           499:                assert(kr == KERN_SUCCESS);
        !           500: 
        !           501:                *treep = (ipc_info_tree_name_t *) copy;
        !           502:                *treeCntp = tree_actual;
        !           503:        }
        !           504: 
        !           505:        return KERN_SUCCESS;
        !           506: }
        !           507: 
        !           508: /*
        !           509:  *     Routine:        mach_port_dnrequest_info
        !           510:  *     Purpose:
        !           511:  *             Returns information about the dead-name requests
        !           512:  *             registered with the named receive right.
        !           513:  *     Conditions:
        !           514:  *             Nothing locked.
        !           515:  *     Returns:
        !           516:  *             KERN_SUCCESS            Retrieved information.
        !           517:  *             KERN_INVALID_TASK       The space is null.
        !           518:  *             KERN_INVALID_TASK       The space is dead.
        !           519:  *             KERN_INVALID_NAME       The name doesn't denote a right.
        !           520:  *             KERN_INVALID_RIGHT      Name doesn't denote receive rights.
        !           521:  */
        !           522: 
        !           523: kern_return_t
        !           524: mach_port_dnrequest_info(
        !           525:        ipc_space_t     space,
        !           526:        mach_port_t     name,
        !           527:        unsigned int    *totalp,
        !           528:        unsigned int    *usedp)
        !           529: {
        !           530:        unsigned int total, used;
        !           531:        ipc_port_t port;
        !           532:        kern_return_t kr;
        !           533: 
        !           534:        if (space == IS_NULL)
        !           535:                return KERN_INVALID_TASK;
        !           536: 
        !           537:        kr = ipc_port_translate_receive(space, name, &port);
        !           538:        if (kr != KERN_SUCCESS)
        !           539:                return kr;
        !           540:        /* port is locked and active */
        !           541: 
        !           542:        if (port->ip_dnrequests == IPR_NULL) {
        !           543:                total = 0;
        !           544:                used = 0;
        !           545:        } else {
        !           546:                ipc_port_request_t dnrequests = port->ip_dnrequests;
        !           547:                ipc_port_request_index_t index;
        !           548: 
        !           549:                total = dnrequests->ipr_size->its_size;
        !           550: 
        !           551:                for (index = 1, used = 0;
        !           552:                     index < total; index++) {
        !           553:                        ipc_port_request_t ipr = &dnrequests[index];
        !           554: 
        !           555:                        if (ipr->ipr_name != MACH_PORT_NULL)
        !           556:                                used++;
        !           557:                }
        !           558:        }
        !           559:        ip_unlock(port);
        !           560: 
        !           561:        *totalp = total;
        !           562:        *usedp = used;
        !           563:        return KERN_SUCCESS;
        !           564: }
        !           565: 
        !           566: /*
        !           567:  *     Routine:        mach_port_kernel_object [kernel call]
        !           568:  *     Purpose:
        !           569:  *             Retrieve the type and address of the kernel object
        !           570:  *             represented by a send or receive right.
        !           571:  *     Conditions:
        !           572:  *             Nothing locked.
        !           573:  *     Returns:
        !           574:  *             KERN_SUCCESS            Retrieved kernel object info.
        !           575:  *             KERN_INVALID_TASK       The space is null.
        !           576:  *             KERN_INVALID_TASK       The space is dead.
        !           577:  *             KERN_INVALID_NAME       The name doesn't denote a right.
        !           578:  *             KERN_INVALID_RIGHT      Name doesn't denote
        !           579:  *                                     send or receive rights.
        !           580:  */
        !           581: 
        !           582: kern_return_t
        !           583: mach_port_kernel_object(
        !           584:        ipc_space_t     space,
        !           585:        mach_port_t     name,
        !           586:        unsigned int    *typep,
        !           587:        vm_offset_t     *addrp)
        !           588: {
        !           589:        ipc_entry_t entry;
        !           590:        ipc_port_t port;
        !           591:        kern_return_t kr;
        !           592: 
        !           593:        kr = ipc_right_lookup_read(space, name, &entry);
        !           594:        if (kr != KERN_SUCCESS)
        !           595:                return kr;
        !           596:        /* space is read-locked and active */
        !           597: 
        !           598:        if ((entry->ie_bits & MACH_PORT_TYPE_SEND_RECEIVE) == 0) {
        !           599:                is_read_unlock(space);
        !           600:                return KERN_INVALID_RIGHT;
        !           601:        }
        !           602: 
        !           603:        port = (ipc_port_t) entry->ie_object;
        !           604:        assert(port != IP_NULL);
        !           605: 
        !           606:        ip_lock(port);
        !           607:        is_read_unlock(space);
        !           608: 
        !           609:        if (!ip_active(port)) {
        !           610:                ip_unlock(port);
        !           611:                return KERN_INVALID_RIGHT;
        !           612:        }
        !           613: 
        !           614:        *typep = (unsigned int) ip_kotype(port);
        !           615:        *addrp = (vm_offset_t) port->ip_kobject;
        !           616:        ip_unlock(port);
        !           617:        return KERN_SUCCESS;
        !           618: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.