(linenum→info "unix/slp.c:2238")

glibc/2.7/hurd/hurdmsg.c

    1: /* Copyright (C) 1992, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
    2:    This file is part of the GNU C Library.
    3: 
    4:    The GNU C Library is free software; you can redistribute it and/or
    5:    modify it under the terms of the GNU Lesser General Public
    6:    License as published by the Free Software Foundation; either
    7:    version 2.1 of the License, or (at your option) any later version.
    8: 
    9:    The GNU C Library is distributed in the hope that it will be useful,
   10:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   11:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   12:    Lesser General Public License for more details.
   13: 
   14:    You should have received a copy of the GNU Lesser General Public
   15:    License along with the GNU C Library; if not, write to the Free
   16:    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   17:    02111-1307 USA.  */
   18: 
   19: #include <hurd.h>
   20: #include <hurd/msg_server.h>
   21: #include <hurd/fd.h>
   22: #include <unistd.h>
   23: #include <limits.h>
   24: #include <string.h>
   25: #include <argz.h>
   26: 
   27: 
   28: #define AUTHCHECK \
   29:   if (auth != mach_task_self () && ! __USEPORT (AUTH, port == auth)) \
   30:     return EPERM
   31: 
   32: 
   33: /* Snarfing and frobbing the init ports.  */
   34: 
   35: kern_return_t
   36:   _S_msg_get_init_port (mach_port_t msgport, mach_port_t auth, int which,
   37:                         mach_port_t *result, mach_msg_type_name_t *result_type)
   38: {
   39:   AUTHCHECK;
   40:   *result_type = MACH_MSG_TYPE_MOVE_SEND;
   41:   /* This function adds a new user reference for the *RESULT it gives back.
   42:      Our reply message uses a move-send right that consumes this reference.  */
   43:   return _hurd_ports_get (which, result);
   44: }
   45: 
   46: kern_return_t
   47: _S_msg_set_init_port (mach_port_t msgport, mach_port_t auth,
   48:                       int which, mach_port_t port)
   49: {
   50:   error_t err;
   51: 
   52:   AUTHCHECK;
   53: 
   54:   err = _hurd_ports_set (which, port);
   55:   if (err == 0)
   56:     __mach_port_deallocate (__mach_task_self (), port);
   57: 
   58:   return 0;
   59: }
   60: 
   61: kern_return_t
   62: _S_msg_get_init_ports (mach_port_t msgport, mach_port_t auth,
   63:                        mach_port_t **ports,
   64:                        mach_msg_type_name_t *ports_type,
   65:                        mach_msg_type_number_t *nports)
   66: {
   67:   mach_msg_type_number_t i;
   68:   error_t err;
   69: 
   70:   AUTHCHECK;
   71: 
   72:   if (err = __vm_allocate (__mach_task_self (), (vm_address_t *) ports,
   73:                            _hurd_nports * sizeof (mach_port_t), 1))
   74:     return err;
   75:   *nports = _hurd_nports;
   76: 
   77:   for (i = 0; i < _hurd_nports; ++i)
   78:     /* This function adds a new user ref for the *RESULT it gives back.
   79:        Our reply message uses move-send rights that consumes this ref.  */
   80:     if (err = _hurd_ports_get (i, &(*ports)[i]))
   81:       {
   82:         /* Died part way through.  Deallocate the ports already fetched.  */
   83:         while (i-- > 0)
   84:           __mach_port_deallocate (__mach_task_self (), (*ports)[i]);
   85:         __vm_deallocate (__mach_task_self (),
   86:                          (vm_address_t) *ports,
   87:                          *nports * sizeof (mach_port_t));
   88:         return err;
   89:       }
   90: 
   91:   *ports_type = MACH_MSG_TYPE_MOVE_SEND;
   92:   return 0;
   93: }
   94: 
   95: kern_return_t
   96: _S_msg_set_init_ports (mach_port_t msgport, mach_port_t auth,
   97:                        mach_port_t *ports, mach_msg_type_number_t nports)
   98: {
   99:   mach_msg_type_number_t i;
  100:   error_t err;
  101: 
  102:   AUTHCHECK;
  103: 
  104:   for (i = 0; i < _hurd_nports; ++i)
  105:     {
  106:       if (err = _hurd_ports_set (i, ports[i]))
  107:         return err;
  108:       else
  109:         __mach_port_deallocate (__mach_task_self (), ports[i]);
  110:     }
  111: 
  112:   return 0;
  113: }
  114: ^L
  115: /* Snarfing and frobbing the init ints.  */
  116: 
  117: static kern_return_t
  118: get_int (int which, int *value)
  119: {
  120:   switch (which)
  121:     {
  122:     case INIT_UMASK:
  123:       *value = _hurd_umask;
  124:       return 0;
  125:     case INIT_SIGMASK:
  126:       {
  127:         struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
  128:         __spin_lock (&ss->lock);
  129:         *value = ss->blocked;
  130:         __spin_unlock (&ss->lock);
  131:         return 0;
  132:       }
  133:     case INIT_SIGPENDING:
  134:       {
  135:         struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
  136:         __spin_lock (&ss->lock);
  137:         *value = ss->pending;
  138:         __spin_unlock (&ss->lock);
  139:         return 0;
  140:       }
  141:     case INIT_SIGIGN:
  142:       {
  143:         struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
  144:         sigset_t ign;
  145:         int sig;
  146:         __spin_lock (&ss->lock);
  147:         __sigemptyset (&ign);
  148:         for (sig = 1; sig < NSIG; ++sig)
  149:           if (ss->actions[sig].sa_handler == SIG_IGN)
  150:             __sigaddset (&ign, sig);
  151:         __spin_unlock (&ss->lock);
  152:         *value = ign;
  153:         return 0;
  154:       }
  155:     default:
  156:       return EINVAL;
  157:     }
  158: }
  159: 
  160: kern_return_t
  161: _S_msg_get_init_int (mach_port_t msgport, mach_port_t auth,
  162:                      int which, int *value)
  163: {
  164:   AUTHCHECK;
  165: 
  166:   return get_int (which, value);
  167: }
  168: 
  169: kern_return_t
  170: _S_msg_get_init_ints (mach_port_t msgport, mach_port_t auth,
  171:                       int **values, mach_msg_type_number_t *nvalues)
  172: {
  173:   error_t err;
  174:   mach_msg_type_number_t i;
  175: 
  176:   AUTHCHECK;
  177: 
  178:   if (err = __vm_allocate (__mach_task_self (), (vm_address_t *) values,
  179:                            INIT_INT_MAX * sizeof (int), 1))
  180:     return err;
  181:   *nvalues = INIT_INT_MAX;
  182: 
  183:   for (i = 0; i < INIT_INT_MAX; ++i)
  184:     switch (err = get_int (i, &(*values)[i]))
  185:       {
  186:       case 0:                   /* Success.  */
  187:         break;
  188:       case EINVAL:              /* Unknown index.  */
  189:         (*values)[i] = 0;
  190:         break;
  191:       default:                  /* Lossage.  */
  192:         __vm_deallocate (__mach_task_self (),
  193:                          (vm_address_t) *values, INIT_INT_MAX * sizeof (int));
  194:         return err;
  195:       }
  196: 
  197:   return 0;
  198: }
  199: 
  200: 
  201: static kern_return_t
  202: set_int (int which, int value)
  203: {
  204:   switch (which)
  205:     {
  206:     case INIT_UMASK:
  207:       _hurd_umask = value;
  208:       return 0;
  209: 
  210:       /* These are pretty odd things to do.  But you asked for it.  */
  211:     case INIT_SIGMASK:
  212:       {
  213:         struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
  214:         __spin_lock (&ss->lock);
  215:         ss->blocked = value;
  216:         __spin_unlock (&ss->lock);
  217:         return 0;
  218:       }
  219:     case INIT_SIGPENDING:
  220:       {
  221:         struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
  222:         __spin_lock (&ss->lock);
  223:         ss->pending = value;
  224:         __spin_unlock (&ss->lock);
  225:         return 0;
  226:       }
  227:     case INIT_SIGIGN:
  228:       {
  229:         struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
  230:         int sig;
  231:         const sigset_t ign = value;
  232:         __spin_lock (&ss->lock);
  233:         for (sig = 1; sig < NSIG; ++sig)
  234:           {
  235:             if (__sigismember (&ign, sig))
  236:               ss->actions[sig].sa_handler = SIG_IGN;
  237:             else if (ss->actions[sig].sa_handler == SIG_IGN)
  238:               ss->actions[sig].sa_handler = SIG_DFL;
  239:           }
  240:         __spin_unlock (&ss->lock);
  241:         return 0;
  242: 
  243:       case INIT_TRACEMASK:
  244:         _hurdsig_traced = value;
  245:         return 0;
  246:       }
  247:     default:
  248:       return EINVAL;
  249:     }
  250: }
  251: 
  252: kern_return_t
  253: _S_msg_set_init_int (mach_port_t msgport, mach_port_t auth,
  254:                      int which, int value)
  255: {
  256:   AUTHCHECK;
  257: 
  258:   return set_int (which, value);
  259: }
  260: 
  261: kern_return_t
  262: _S_msg_set_init_ints (mach_port_t msgport, mach_port_t auth,
  263:                       int *values, mach_msg_type_number_t nvalues)
  264: {
  265:   error_t err;
  266:   mach_msg_type_number_t i;
  267: 
  268:   AUTHCHECK;
  269: 
  270:   for (i = 0; i < INIT_INT_MAX; ++i)
  271:     switch (err = set_int (i, values[i]))
  272:       {
  273:       case 0:                   /* Success.  */
  274:         break;
  275:       case EINVAL:              /* Unknown index.  */
  276:         break;
  277:       default:                  /* Lossage.  */
  278:         return err;
  279:       }
  280: 
  281:   return 0;
  282: }
  283: ^L
  284: 
  285: kern_return_t
  286: _S_msg_get_fd (mach_port_t msgport, mach_port_t auth, int which,
  287:                mach_port_t *result, mach_msg_type_name_t *result_type)
  288: {
  289:   AUTHCHECK;
  290: 
  291:   /* This creates a new user reference for the send right.
  292:      Our reply message will move that reference to the caller.  */
  293:   *result = __getdport (which);
  294:   if (*result == MACH_PORT_NULL)
  295:     return errno;
  296:   *result_type = MACH_MSG_TYPE_MOVE_SEND;
  297: 
  298:   return 0;
  299: }
  300: 
  301: kern_return_t
  302: _S_msg_set_fd (mach_port_t msgport, mach_port_t auth,
  303:                int which, mach_port_t port)
  304: {
  305:   AUTHCHECK;
  306: 
  307:   /* We consume the reference if successful.  */
  308:   return HURD_FD_USE (which, (_hurd_port2fd (descriptor, port, 0), 0));
  309: }
  310: ^L
  311: /* Snarfing and frobbing environment variables.  */
  312: 
  313: kern_return_t
  314: _S_msg_get_env_variable (mach_port_t msgport,
  315:                          char *variable,
  316:                          char **data, mach_msg_type_number_t *datalen)
  317: {
  318:   error_t err;
  319:   mach_msg_type_number_t valuelen;
  320:   const char *value = getenv (variable);
  321: 
  322:   if (value == NULL)
  323:     return ENOENT;
  324: 
  325:   valuelen = strlen (value);
  326:   if (valuelen > *datalen)
  327:     {
  328:       if (err = __vm_allocate (__mach_task_self (), 
  329:                                (vm_address_t *) data, valuelen, 1))
  330:         return err;
  331:     }
  332: 
  333:   memcpy (*data, value, valuelen);
  334:   *datalen = valuelen;
  335: 
  336:   return 0;
  337: }
  338: 
  339: 
  340: kern_return_t
  341: _S_msg_set_env_variable (mach_port_t msgport, mach_port_t auth,
  342:                          char *variable,
  343:                          char *value,
  344:                          int replace)
  345: {
  346:   AUTHCHECK;
  347: 
  348:   if (setenv (variable, value, replace)) /* XXX name space */
  349:     return errno;
  350:   return 0;
  351: }
  352: 
  353: kern_return_t
  354: _S_msg_get_environment (mach_port_t msgport,
  355:                         char **data, mach_msg_type_number_t *datalen)
  356: {
  357:   /* Pack the environment into an array with nulls separating elements.  */
  358:   if (__environ != NULL)
  359:     {
  360:       char *ap, **p;
  361:       size_t envlen = 0;
  362: 
  363:       for (p = __environ; *p != NULL; ++p)
  364:         envlen += strlen (*p) + 1;
  365: 
  366:       if (envlen > *datalen)
  367:         {
  368:           if (__vm_allocate (__mach_task_self (),
  369:                              (vm_address_t *) data, envlen, 1))
  370:             return ENOMEM;
  371:         }
  372: 
  373:       ap = *data;
  374:       for (p = __environ; *p != NULL; ++p)
  375:         ap = __memccpy (ap, *p, '\0', ULONG_MAX);
  376: 
  377:       *datalen = envlen;
  378:     }
  379:   else
  380:     *datalen = 0;
  381: 
  382:   return 0;
  383: }
  384: 
  385: kern_return_t
  386: _S_msg_set_environment (mach_port_t msgport, mach_port_t auth,
  387:                         char *data, mach_msg_type_number_t datalen)
  388: {
  389:   int _hurd_split_args (char *, mach_msg_type_number_t, char **);
  390:   int envc;
  391:   char **envp;
  392: 
  393:   AUTHCHECK;
  394: 
  395:   envc = __argz_count (data, datalen);
  396:   envp = malloc ((envc + 1) * sizeof (char *));
  397:   if (envp == NULL)
  398:     return errno;
  399:   __argz_extract (data, datalen, envp);
  400:   __environ = envp;             /* XXX cooperate with loadenv et al */
  401:   return 0;
  402: }
  403: ^L
  404: 
  405: /* XXX */
  406: 
  407: kern_return_t
  408: _S_msg_get_dtable (mach_port_t process,
  409:                    mach_port_t refport,
  410:                    portarray_t *dtable,
  411:                    mach_msg_type_name_t *dtablePoly,
  412:                    mach_msg_type_number_t *dtableCnt)
  413: { return EOPNOTSUPP; }
  414: 
  415: kern_return_t
  416: _S_msg_set_dtable (mach_port_t process,
  417:                    mach_port_t refport,
  418:                    portarray_t dtable,
  419:                    mach_msg_type_number_t dtableCnt)
  420: { return EOPNOTSUPP; }
Syntax (Markdown)