Changeset 1629


Ignore:
Timestamp:
Nov 14, 2004, 6:28:02 AM (21 years ago)
Author:
bird
Message:

Signals, processes and stuff.

Location:
trunk/src/emx/src/lib
Files:
9 added
6 deleted
18 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/emx/src/lib/libc.def

    • Property cvs2svn:cvs-rev changed from 1.76 to 1.77
    r1628 r1629  
    686686    "__std_geteuid" @708
    687687    "__std_getgid" @709
    688     "__std_getgrgid" @710
     688;fixme    "__std_getgrgid" @710
    689689    "__std_getgrnam" @711
    690690    "__std_getgroups" @712
     
    696696    "__std_getpid" @718
    697697    "__std_getppid" @719
    698 ;    "__std_getpw" @720
     698;fixme    "__std_getpw" @720
    699699    "__std_getpwent" @721
    700     "__std_getpwnam" @722
    701     "__std_getpwuid" @723
     700;fixme    "__std_getpwnam" @722
     701;fixme    "__std_getpwuid" @723
    702702    "__std_getrlimit" @724
    703703    "__std_gets" @725
     
    12301230    "__std_sigwait" @1252
    12311231    "__std_sigwaitinfo" @1253
    1232     "___libc_Back_signalVerifyPGrp" @1254
    1233     "___libc_Back_signalVerifyPid" @1255
    1234     "___libc_Back_signalRaise" @1256
    1235     "___libc_Back_signalSendPGrp" @1257
    1236     "___libc_Back_signalSendPid" @1258
    1237     "___libc_Back_signalAction" @1259
    1238     "___libc_Back_signalFreeWorker" @1260
    1239     "___libc_Back_signalStack" @1261
    1240     "___libc_Back_signalMask" @1262
    1241     "___libc_Back_signalInterrupt" @1263
    1242     "___libc_Back_signalPending" @1264
    1243     "___libc_Back_signalSuspend" @1265
    1244     "___libc_Back_signalWait" @1266
     1232    "__std_sigqueue" @1254
     1233    "__std_sigset" @1255
     1234    "_getgrgid" @1256
     1235    "_getpwnam" @1257
     1236    "_getpwuid" @1258
     1237    "___libc_Back_processGetEffGid" @1259
     1238    "___libc_Back_processGetEffUid" @1260
     1239    "___libc_Back_processGetGid" @1261
     1240    "___libc_Back_processGetUid" @1262
     1241    "___libc_Back_processSetGid" @1263
     1242    "___libc_Back_processSetGidAll" @1264
     1243    "___libc_Back_processSetUid" @1265
     1244    "___libc_Back_processSetUidAll" @1266
     1245    "___libc_Back_processWait" @1267
     1246    "___libc_Back_signalAction" @1268
     1247    "___libc_Back_signalInterrupt" @1269
     1248    "___libc_Back_signalMask" @1270
     1249    "___libc_Back_signalPending" @1271
     1250    "___libc_Back_signalQueue" @1272
     1251    "___libc_Back_signalRaise" @1273
     1252    "___libc_Back_signalSendPGrp" @1274
     1253    "___libc_Back_signalSendPid" @1275
     1254    "___libc_Back_signalStack" @1276
     1255    "___libc_Back_signalSuspend" @1277
     1256    "___libc_Back_signalWait" @1278
     1257    "__std_setegid" @1279
     1258    "__std_seteuid" @1280
     1259    "__std_setregid" @1281
     1260    "__std_setresgid" @1282
     1261    "__std_setresuid" @1283
     1262    "__std_setreuid" @1284
     1263    "__std_setrgid" @1285
     1264    "__std_setruid" @1286
     1265    "__std_waitid" @1287
  • trunk/src/emx/src/lib/libc.smak

    • Property cvs2svn:cvs-rev changed from 1.50 to 1.51
    r1628 r1629  
    3232.INSDIR = lib/
    3333.TKEEP  := 1
    34 include mklib.smak
     34#include mklib.smak
    3535
    3636
     
    3838.TKIND  := aout log
    3939.TKEEP  := 1
    40 include mklib.smak
     40#include mklib.smak
    4141
    4242# Build libc.a last since LIBC.DLL needs .OBJS from libc.a
     
    312312all: libc-dll
    313313libc-dll: emxbind emxexp app alias libc libos2 libos2@omf liblazyimp liblazyimp@omf libend \
    314                         $(LIBC.DIRS) $(LIBC.DLL) $(LIBC.IMPLIB) \
     314                        $(LIBC.DIRS) $(LIBC.DLL) $(LIBC.IMPLIB)
     315disabled.0 = \
    315316                        $(LIBC.LOG.DIRS) $(LIBC.LOG.DLL) \
    316317                        $(LIBC.PRF.DIRS) $(LIBC.PRF.DLL) \
     
    320321INS.FILES       += $(INS)lib/$(notdir $(LIBC.DLL)) \
    321322  $(INS)lib/$(notdir $(LIBC.DLL:.dll=.map)) \
    322   $(addprefix $(INS)lib/,$(notdir $(LIBC.IMPLIB))) \
     323  $(addprefix $(INS)lib/,$(notdir $(LIBC.IMPLIB)))
     324disabled.1 = \
    323325  $(INS)lib/$(notdir $(LIBC.LOG.DLL)) \
    324326  $(INS)lib/$(notdir $(LIBC.LOG.DLL).map) \
  • trunk/src/emx/src/lib/misc/getegid.c

    • Property cvs2svn:cvs-rev changed from 1.5 to 1.6
    r1628 r1629  
    1 /* getegid.c (emx+gcc) -- Copyright (c) 1994-1995 by Eberhard Mattes */
     1/* $Id: $ */
     2/** @file
     3 *
     4 * LIBC - getegid().
     5 *
     6 * Copyright (c) 2004 knut st. osmundsen <bird@innotek.de>
     7 *
     8 *
     9 * This file is part of InnoTek LIBC.
     10 *
     11 * InnoTek LIBC is free software; you can redistribute it and/or modify
     12 * it under the terms of the GNU Lesser General Public License as published
     13 * by the Free Software Foundation; either version 2 of the License, or
     14 * (at your option) any later version.
     15 *
     16 * InnoTek LIBC is distributed in the hope that it will be useful,
     17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     19 * GNU Lesser General Public License for more details.
     20 *
     21 * You should have received a copy of the GNU Lesser General Public License
     22 * along with InnoTek LIBC; if not, write to the Free Software
     23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     24 *
     25 */
    226
     27
     28/*******************************************************************************
     29*   Header Files                                                               *
     30*******************************************************************************/
    331#include "libc-alias.h"
     32#include <errno.h>
    433#include <unistd.h>
    5 #include <sys/types.h>
     34#include <InnoTekLIBC/backend.h>
     35#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_PROCESS
     36#include <InnoTekLIBC/logstrict.h>
    637
    7 gid_t _STD(getegid) (void)
     38/**
     39 * Gets the effective group id of the current process.
     40 * @returns Effecitve group id.
     41 */
     42gid_t _STD(getegid)(void)
    843{
    9   return 0;
     44    LIBCLOG_ENTER("\n");
     45    gid_t gid = __libc_Back_processGetEffGid();
     46    LIBCLOG_RETURN_INT(gid);
    1047}
  • trunk/src/emx/src/lib/misc/geteuid.c

    • Property cvs2svn:cvs-rev changed from 1.5 to 1.6
    r1628 r1629  
    1 /* geteuid.c (emx+gcc) -- Copyright (c) 1994-1995 by Eberhard Mattes */
     1/* $Id: $ */
     2/** @file
     3 *
     4 * LIBC - geteuid().
     5 *
     6 * Copyright (c) 2004 knut st. osmundsen <bird@innotek.de>
     7 *
     8 *
     9 * This file is part of InnoTek LIBC.
     10 *
     11 * InnoTek LIBC is free software; you can redistribute it and/or modify
     12 * it under the terms of the GNU Lesser General Public License as published
     13 * by the Free Software Foundation; either version 2 of the License, or
     14 * (at your option) any later version.
     15 *
     16 * InnoTek LIBC is distributed in the hope that it will be useful,
     17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     19 * GNU Lesser General Public License for more details.
     20 *
     21 * You should have received a copy of the GNU Lesser General Public License
     22 * along with InnoTek LIBC; if not, write to the Free Software
     23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     24 *
     25 */
    226
     27
     28/*******************************************************************************
     29*   Header Files                                                               *
     30*******************************************************************************/
    331#include "libc-alias.h"
     32#include <errno.h>
    433#include <unistd.h>
    5 #include <sys/types.h>
     34#include <InnoTekLIBC/backend.h>
     35#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_PROCESS
     36#include <InnoTekLIBC/logstrict.h>
    637
    7 uid_t _STD(geteuid) (void)
     38/**
     39 * Gets the effective group id of the current process.
     40 *
     41 * @returns Effective group id.
     42 */
     43uid_t _STD(geteuid)(void)
    844{
    9   return 0;
     45    LIBCLOG_ENTER("\n");
     46    uid_t uid = __libc_Back_processGetEffUid();
     47    LIBCLOG_RETURN_INT(uid);
    1048}
     49
  • trunk/src/emx/src/lib/misc/getgid.c

    • Property cvs2svn:cvs-rev changed from 1.4 to 1.5
    r1628 r1629  
    1 /* getgid.c (emx+gcc) -- Copyright (c) 1994-1995 by Eberhard Mattes */
     1/* $Id: $ */
     2/** @file
     3 *
     4 * LIBC - getgid().
     5 *
     6 * Copyright (c) 2004 knut st. osmundsen <bird@innotek.de>
     7 *
     8 *
     9 * This file is part of InnoTek LIBC.
     10 *
     11 * InnoTek LIBC is free software; you can redistribute it and/or modify
     12 * it under the terms of the GNU Lesser General Public License as published
     13 * by the Free Software Foundation; either version 2 of the License, or
     14 * (at your option) any later version.
     15 *
     16 * InnoTek LIBC is distributed in the hope that it will be useful,
     17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     19 * GNU Lesser General Public License for more details.
     20 *
     21 * You should have received a copy of the GNU Lesser General Public License
     22 * along with InnoTek LIBC; if not, write to the Free Software
     23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     24 *
     25 */
    226
     27
     28/*******************************************************************************
     29*   Header Files                                                               *
     30*******************************************************************************/
    331#include "libc-alias.h"
     32#include <errno.h>
    433#include <unistd.h>
    5 #include <sys/types.h>
     34#include <InnoTekLIBC/backend.h>
     35#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_PROCESS
     36#include <InnoTekLIBC/logstrict.h>
    637
    7 gid_t _STD(getgid) (void)
     38/**
     39 * Gets the real group id of the current process.
     40 * @returns Real group id.
     41 */
     42gid_t _STD(getgid)(void)
    843{
    9   return 0;
     44    LIBCLOG_ENTER("\n");
     45    gid_t gid = __libc_Back_processGetGid();
     46    LIBCLOG_RETURN_INT(gid);
    1047}
  • trunk/src/emx/src/lib/misc/getuid.c

    • Property cvs2svn:cvs-rev changed from 1.4 to 1.5
    r1628 r1629  
    1 /* getuid.c (emx+gcc) -- Copyright (c) 1994-1995 by Eberhard Mattes */
     1/* $Id: $ */
     2/** @file
     3 *
     4 * LIBC - getuid().
     5 *
     6 * Copyright (c) 2004 knut st. osmundsen <bird@innotek.de>
     7 *
     8 *
     9 * This file is part of InnoTek LIBC.
     10 *
     11 * InnoTek LIBC is free software; you can redistribute it and/or modify
     12 * it under the terms of the GNU Lesser General Public License as published
     13 * by the Free Software Foundation; either version 2 of the License, or
     14 * (at your option) any later version.
     15 *
     16 * InnoTek LIBC is distributed in the hope that it will be useful,
     17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     19 * GNU Lesser General Public License for more details.
     20 *
     21 * You should have received a copy of the GNU Lesser General Public License
     22 * along with InnoTek LIBC; if not, write to the Free Software
     23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     24 *
     25 */
    226
     27
     28/*******************************************************************************
     29*   Header Files                                                               *
     30*******************************************************************************/
    331#include "libc-alias.h"
     32#include <errno.h>
    433#include <unistd.h>
    5 #include <sys/types.h>
     34#include <InnoTekLIBC/backend.h>
     35#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_PROCESS
     36#include <InnoTekLIBC/logstrict.h>
    637
    7 uid_t _STD(getuid) (void)
     38/**
     39 * Gets the real group id of the current process.
     40 *
     41 * @returns Real group id.
     42 */
     43uid_t _STD(getuid)(void)
    844{
    9   return 0;
     45    LIBCLOG_ENTER("\n");
     46    uid_t uid = __libc_Back_processGetUid();
     47    LIBCLOG_RETURN_INT(uid);
    1048}
     49
  • trunk/src/emx/src/lib/misc/setgid.c

    • Property cvs2svn:cvs-rev changed from 1.4 to 1.5
    r1628 r1629  
    1 /* setgid.c (emx+gcc) -- Copyright (c) 1994-1995 by Eberhard Mattes */
     1/* $Id: $ */
     2/** @file
     3 *
     4 * LIBC - setgid().
     5 *
     6 * Copyright (c) 2004 knut st. osmundsen <bird@innotek.de>
     7 *
     8 *
     9 * This file is part of InnoTek LIBC.
     10 *
     11 * InnoTek LIBC is free software; you can redistribute it and/or modify
     12 * it under the terms of the GNU Lesser General Public License as published
     13 * by the Free Software Foundation; either version 2 of the License, or
     14 * (at your option) any later version.
     15 *
     16 * InnoTek LIBC is distributed in the hope that it will be useful,
     17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     19 * GNU Lesser General Public License for more details.
     20 *
     21 * You should have received a copy of the GNU Lesser General Public License
     22 * along with InnoTek LIBC; if not, write to the Free Software
     23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     24 *
     25 */
    226
     27
     28/*******************************************************************************
     29*   Header Files                                                               *
     30*******************************************************************************/
    331#include "libc-alias.h"
     32#include <errno.h>
    433#include <unistd.h>
    5 #include <errno.h>
    6 #include <sys/types.h>
     34#include <InnoTekLIBC/backend.h>
     35#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_PROCESS
     36#include <InnoTekLIBC/logstrict.h>
    737
    8 int _STD(setgid) (gid_t gid)
     38/**
     39 * Sets the real group id of the current process.
     40 * If there user is privilegde all three group ids will be set.
     41 *
     42 * Non privilegde users may only set it to the real group id or the saved group id.
     43 *
     44 * @returns 0 on success.
     45 * @returns -1 and errno on error.
     46 * @param   gid     The new real group id.
     47 *                  For superusers also the new effective and saved group id.
     48 */
     49int _STD(setgid)(gid_t gid)
    950{
    10   if (gid != 0)
    11     {
    12       errno = EINVAL;
    13       return -1;
    14     }
    15   return 0;
     51    LIBCLOG_ENTER("gid=%d (%#x)\n", gid, gid);
     52    int rc = __libc_Back_processSetGid(gid);
     53    if (!rc)
     54        LIBCLOG_RETURN_INT(0);
     55    errno = -rc;
     56    LIBCLOG_RETURN_INT(-1);
    1657}
     58
  • trunk/src/emx/src/lib/misc/setuid.c

    • Property cvs2svn:cvs-rev changed from 1.4 to 1.5
    r1628 r1629  
    1 /* setuid.c (emx+gcc) -- Copyright (c) 1994-1995 by Eberhard Mattes */
     1/* $Id: $ */
     2/** @file
     3 *
     4 * LIBC - setuid().
     5 *
     6 * Copyright (c) 2004 knut st. osmundsen <bird@innotek.de>
     7 *
     8 *
     9 * This file is part of InnoTek LIBC.
     10 *
     11 * InnoTek LIBC is free software; you can redistribute it and/or modify
     12 * it under the terms of the GNU Lesser General Public License as published
     13 * by the Free Software Foundation; either version 2 of the License, or
     14 * (at your option) any later version.
     15 *
     16 * InnoTek LIBC is distributed in the hope that it will be useful,
     17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     19 * GNU Lesser General Public License for more details.
     20 *
     21 * You should have received a copy of the GNU Lesser General Public License
     22 * along with InnoTek LIBC; if not, write to the Free Software
     23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     24 *
     25 */
    226
     27
     28/*******************************************************************************
     29*   Header Files                                                               *
     30*******************************************************************************/
    331#include "libc-alias.h"
     32#include <errno.h>
    433#include <unistd.h>
    5 #include <errno.h>
    6 #include <sys/types.h>
     34#include <InnoTekLIBC/backend.h>
     35#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_PROCESS
     36#include <InnoTekLIBC/logstrict.h>
    737
    8 int _STD(setuid) (uid_t uid)
     38/**
     39 * Sets the real user id of the current process.
     40 * If there user is privilegde all three user ids will be set.
     41 *
     42 * Non privilegde users may only set it to the real user id or the saved user id.
     43 *
     44 * @returns 0 on success.
     45 * @returns -1 and errno on error.
     46 * @param   uid     The new real users id.
     47 *                  For superusers also the new effective and saved user id.
     48 */
     49int _STD(setuid)(uid_t uid)
    950{
    10   if (uid != 0)
    11     {
    12       errno = EINVAL;
    13       return -1;
    14     }
    15   return 0;
     51    LIBCLOG_ENTER("uid=%d (%#x)\n", uid, uid);
     52    int rc = __libc_Back_processSetUid(uid);
     53    if (!rc)
     54        LIBCLOG_RETURN_INT(0);
     55    errno = -rc;
     56    LIBCLOG_RETURN_INT(-1);
    1657}
     58
  • trunk/src/emx/src/lib/misc/sysconf.c

    • Property cvs2svn:cvs-rev changed from 1.4 to 1.5
    r1628 r1629  
    1111long _STD(sysconf) (int name)
    1212{
    13   switch (name)
     13    switch (name)
    1414    {
    15     case _SC_ARG_MAX:
    16       return _POSIX_ARG_MAX;
     15        case _SC_ARG_MAX:
     16            return _POSIX_ARG_MAX;
    1717
    18     case _SC_CHILD_MAX:
    19       return _POSIX_CHILD_MAX;
     18        case _SC_CHILD_MAX:
     19            return _POSIX_CHILD_MAX;
    2020
    21     case _SC_CLK_TCK:
    22       /* On emx, CLK_TCK is a constant.  On other systems, it may a
    23          macro which calls sysconf (_SC_CLK_TCK). */
     21        case _SC_CLK_TCK:
     22            /* On emx, CLK_TCK is a constant.  On other systems, it may a
     23               macro which calls sysconf (_SC_CLK_TCK). */
    2424
    25       return CLK_TCK;
     25            return CLK_TCK;
    2626
    27     case _SC_NGROUPS_MAX:
    28       return _POSIX_NGROUPS_MAX;
     27        case _SC_NGROUPS_MAX:
     28            return _POSIX_NGROUPS_MAX;
    2929
    30     case _SC_OPEN_MAX:
    31       return _POSIX_OPEN_MAX;
     30        case _SC_OPEN_MAX:
     31            return _POSIX_OPEN_MAX;
    3232
    33     case _SC_STREAM_MAX:
    34       return _POSIX_STREAM_MAX;
     33        case _SC_STREAM_MAX:
     34            return _POSIX_STREAM_MAX;
    3535
    36     case _SC_TZNAME_MAX:
    37       return _POSIX_TZNAME_MAX;
     36        case _SC_TZNAME_MAX:
     37            return _POSIX_TZNAME_MAX;
    3838
    39     case _SC_JOB_CONTROL:
    40       return -1;
     39        case _SC_JOB_CONTROL:
     40            return -1;
    4141
    42     case _SC_SAVED_IDS:
    43       return -1;
     42        case _SC_SAVED_IDS:
     43            return -1;
    4444
    45     case _SC_VERSION:
    46       return _POSIX_VERSION;
     45        case _SC_VERSION:
     46            return _POSIX_VERSION;
    4747
    48     default:
    49       errno = EINVAL;
    50       return -1;
     48        case _SC_SIGQUEUE_MAX:
     49            return _POSIX_SIGQUEUE_MAX;
     50
     51        default:
     52            errno = EINVAL;
     53            return -1;
    5154    }
    5255}
  • trunk/src/emx/src/lib/process/kill.c

    • Property cvs2svn:cvs-rev changed from 1.5 to 1.6
    r1628 r1629  
    7272
    7373    /*
    74      * Validate the process specification.
     74     * Call backend to do the rest.
    7575     */
    7676    if (pid > 0)
    77         rc = __libc_Back_signalVerifyPid(pid);
     77        rc = __libc_Back_signalSendPid(pid, iSignalNo);
    7878    else /* (pid <= 0) */
    79         rc = __libc_Back_signalVerifyPGrp(-pid);
     79        rc = __libc_Back_signalSendPGrp(-pid, iSignalNo);
    8080    if (!rc)
    81     {
    82         /*
    83          * The pid is valid, if iSignalNo is 0 then we're done.
    84          */
    85         if (!iSignalNo)
    86             LIBCLOG_RETURN_INT(0);
    87 
    88         /*
    89          * Send signals.
    90          */
    91         if (pid > 0)
    92             rc = __libc_Back_signalSendPid(pid, iSignalNo);
    93         else
    94             rc = __libc_Back_signalSendPGrp(-pid, iSignalNo);
    95         if (!rc)
    96             LIBCLOG_RETURN_INT(0);
    97     }
    98     /* failure */
     81        LIBCLOG_RETURN_INT(0);
    9982    errno = -rc;
    10083    LIBCLOG_RETURN_INT(-1);
  • trunk/src/emx/src/lib/sys/b_processWait.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1628 r1629  
    373373     * (and besides it's deadly important to do it!)
    374374     */
    375     __LIBC_EXIT_REASON  enmReason;
    376     int                 iExitCode;
    377     if (!__libc_spmReapChild(pid, &iExitCode, &enmReason))
     375    __LIBC_SPMCHILDNOTIFY Notify = {NULL, sizeof(Notify), 0};
     376    if (!__libc_spmQueryChildNotification(pid, &Notify))
    378377    {
    379378        /*
     
    382381         */
    383382        LIBCLOG_MSG2("SPM Child %#lx (%ld) for reason %d and with code %d (%#x).\n",
    384                      pid, pid, enmReason, iExitCode, iExitCode);
    385 
    386         switch (enmReason)
     383                     pid, pid, Notify.enmDeathReason, Notify.iExitCode, Notify.iExitCode);
     384
     385        switch (Notify.enmDeathReason)
    387386        {
    388387            case __LIBC_EXIT_REASON_EXIT:
    389388                pWait->uCode    = CLD_EXITED;
    390                 pWait->uStatus  = W_EXITCODE(iExitCode, 0);
     389                pWait->uStatus  = W_EXITCODE(Notify.iExitCode, 0);
    391390                break;
    392391
    393392            case __LIBC_EXIT_REASON_HARDERROR:
    394393                pWait->uCode    = CLD_KILLED;
    395                 pWait->uStatus  = W_EXITCODE(iExitCode, SIGBUS);
     394                pWait->uStatus  = W_EXITCODE(Notify.iExitCode, SIGBUS);
    396395                break;
    397396
     
    399398            case __LIBC_EXIT_REASON_XCPT:
    400399                pWait->uCode    = CLD_DUMPED;
    401                 pWait->uStatus  = W_EXITCODE(iExitCode, SIGSEGV);
     400                pWait->uStatus  = W_EXITCODE(Notify.iExitCode, SIGSEGV);
    402401                break;
    403402
    404403            case __LIBC_EXIT_REASON_KILL:
    405404                pWait->uCode    = CLD_KILLED;
    406                 pWait->uStatus  = W_EXITCODE(iExitCode, SIGKILL);
     405                pWait->uStatus  = W_EXITCODE(Notify.iExitCode, SIGKILL);
    407406                break;
    408407
    409408            default:
    410                 if (    enmReason >= __LIBC_EXIT_REASON_SIGNAL_BASE
    411                     &&  enmReason <= __LIBC_EXIT_REASON_SIGNAL_MAX)
     409                if (    Notify.enmDeathReason >= __LIBC_EXIT_REASON_SIGNAL_BASE
     410                    &&  Notify.enmDeathReason <= __LIBC_EXIT_REASON_SIGNAL_MAX)
    412411                {
    413412                    pWait->uCode    = CLD_KILLED;
    414                     pWait->uStatus  = W_EXITCODE(iExitCode, enmReason - __LIBC_EXIT_REASON_SIGNAL_BASE);
     413                    pWait->uStatus  = W_EXITCODE(Notify.iExitCode, Notify.enmDeathReason - __LIBC_EXIT_REASON_SIGNAL_BASE);
    415414                    break;
    416415                }
    417416                /* fall thru */
    418417            case __LIBC_EXIT_REASON_NONE:
    419                 LIBCLOG_MSG2("Unknown death reason %d\n", enmReason);
     418                LIBCLOG_MSG2("Unknown death reason %d\n", Notify.enmDeathReason);
    420419                break;
    421420        }
  • trunk/src/emx/src/lib/sys/b_signalQueue.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1628 r1629  
    5252{
    5353    LIBCLOG_ENTER("pid=%d iSignalNo=%d SigVal=%p\n", pid, iSignalNo, SigVal.sigval_ptr);
    54     int                 rc;
    5554
    5655    /*
     
    6665     * Verify pid.
    6766     */
    68     rc = __libc_Back_signalVerifyPid(pid);
    69     if (!rc && iSignalNo)
     67    siginfo_t   SigInfo = {0};
     68    SigInfo.si_flags   |= __LIBC_SI_QUEUED;
     69    SigInfo.si_value    = SigVal;
     70    SigInfo.si_signo    = iSignalNo;
     71    int rc;
     72    if (pid == _sys_pid)
    7073    {
    71         siginfo_t   SigInfo = {0};
    72         SigInfo.si_flags   |= __LIBC_SI_QUEUED;
    73         SigInfo.si_value    = SigVal;
    74         SigInfo.si_signo    = iSignalNo;
    75         if (pid == _sys_pid)
     74        if (iSignalNo)
    7675            rc = __libc_back_signalQueueSelf(iSignalNo, &SigInfo);
    77         else
    78             rc = __libc_back_signalSendPidOther(pid, iSignalNo, &SigInfo);
     76        else /* permission only */
     77            rc = 0;
    7978    }
     79    else
     80        rc = __libc_back_signalSendPidOther(pid, iSignalNo, &SigInfo);
    8081
    8182    /*
  • trunk/src/emx/src/lib/sys/b_signalSendPid.c

    • Property cvs2svn:cvs-rev changed from 1.3 to 1.4
    r1628 r1629  
    4040#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_BACK_SIGNAL
    4141#include <InnoTekLIBC/logstrict.h>
     42#include "signals.h"
    4243#include "syscalls.h"
    4344
     
    4647 * Send a signal to a process.
    4748 *
     49 * Special case for iSignalNo equal to 0, where no signal is sent but permissions to
     50 * do so is checked.
     51 *
    4852 * @returns 0 on if signal sent.
    4953 * @returns -errno on failure.
     
    5155 * @param   pid         Process Id of the process which the signal is to be sent to.
    5256 * @param   iSignalNo   The signal to send.
    53  * @remark  This Backend Signal API does NOT require the caller to own the signal semaphore.
     57 *                      If 0 no signal is sent, but error handling is done as if.
    5458 */
    5559int     __libc_Back_signalSendPid(pid_t pid, int iSignalNo)
     
    6165     * Validate input.
    6266     */
    63     if (!__SIGSET_SIG_VALID(iSignalNo))
     67    if (!__SIGSET_SIG_VALID(iSignalNo) && iSignalNo != 0)
    6468    {
    6569        LIBC_ASSERTM_FAILED("Invalid signal no. %d\n", iSignalNo);
    6670        LIBCLOG_RETURN_INT(-EINVAL);
    6771    }
    68     if (pid < 0)
     72    if (pid <= 0)
    6973    {
    7074        LIBC_ASSERTM_FAILED("Invalid pid %d\n", pid);
     
    7983    else
    8084    {
    81         rc = __libc_Back_signalRaise(iSignalNo, NULL, NULL, 0);
    82         if (rc > 0)
     85        if (iSignalNo != 0)
     86        {
     87            rc = __libc_Back_signalRaise(iSignalNo, NULL, NULL, 0);
     88            if (rc > 0)
     89                rc = 0;
     90        }
     91        else /* permission check, succeeded. */
    8392            rc = 0;
    8493    }
  • trunk/src/emx/src/lib/sys/b_signalSuspend.c

    • Property cvs2svn:cvs-rev changed from 1.3 to 1.4
    r1628 r1629  
    4141/**
    4242 * Suspends the current thread till a signal have been handled.
    43  * The signal semaphore is owned.
     43 *
     44 * @returns Negative error code (errno) on failure. (always fails)
     45 * @param   pSigSet     Temporary signal mask for the thread.
    4446 */
    4547int         __libc_Back_signalSuspend(const sigset_t *pSigSet)
  • trunk/src/emx/src/lib/sys/filehandles.c

    • Property cvs2svn:cvs-rev changed from 1.14 to 1.15
    r1628 r1629  
    178178            unsigned    i = 0;
    179179            unsigned    c = u.pHdr->cHandles;
    180             unsigned    iFH = u.pHdr->fhStart;
     180            unsigned    iFH = u.pHdr->StartFH;
    181181            switch (u.pHdr->uchType)
    182182            {
     
    359359            {
    360360                u.pStds->Hdr.uchType = __LIBC_SPM_INH_FHB_TYPE_STANDARD;
    361                 u.pStds->Hdr.fhStart = iFH;
     361                u.pStds->Hdr.StartFH = iFH;
    362362                /* walk file handles. */
    363363                for (i = 0; ; )
     
    384384                u.pSockets->Hdr.uchType = enmType == enmFH_Socket44
    385385                    ? __LIBC_SPM_INH_FHB_TYPE_SOCKET_44 : __LIBC_SPM_INH_FHB_TYPE_SOCKET_43;
    386                 u.pSockets->Hdr.fhStart = iFH;
     386                u.pSockets->Hdr.StartFH = iFH;
    387387                /* walk file handles. */
    388388                for (i = 0; ; )
     
    430430    u.pHdr->uchType  = __LIBC_SPM_INH_FHB_TYPE_END;
    431431    u.pHdr->cHandles = 0;
    432     u.pHdr->fhStart  = ~0;
     432    u.pHdr->StartFH  = ~0;
    433433    cb = (uintptr_t)(u.pHdr + 1) - (uintptr_t)pRet;
    434434    *pcb = (cb + 3) & ~3;               /* (This is safe.) */
  • trunk/src/emx/src/lib/sys/sharedpm.c

    • Property cvs2svn:cvs-rev changed from 1.18 to 1.19
    r1628 r1629  
    119119static __LIBC_PSPMPROCESS spmQueryProcessInState(pid_t pid, __LIBC_SPMPROCSTAT enmState);
    120120static unsigned spmTimestamp(void);
    121 static __LIBC_PSPMPROCESS spmRegisterSelf(pid_t pid, pid_t pidParent);
     121static __LIBC_PSPMPROCESS spmRegisterSelf(pid_t pid, pid_t pidParent, pid_t sid);
    122122static __LIBC_PSPMPROCESS spmAllocProcess(void);
    123123static void spmFreeProcess(__LIBC_PSPMPROCESS pProcess);
     124static __LIBC_PSPMCHILDNOTIFY spmAllocChildNotify(void);
     125static void spmFreeChildNotify(__LIBC_PSPMCHILDNOTIFY pNotify);
     126static int spmSigQueueProcess(__LIBC_PSPMPROCESS pProcess, int iSignalNo, siginfo_t *pSigInfo, int fQueued, int fQueueAnyway);
     127static __LIBC_PSPMSIGNAL spmAllocSignal(void);
     128static void spmFreeSignal(__LIBC_PSPMSIGNAL pSig);
    124129static void *spmAlloc(size_t cbSize);
    125130static void *spmAllocSub(size_t cbSize);
     
    170175         * Our selves.
    171176         */
    172         if (gpSPMSelf)
     177        if (    gpSPMSelf
     178            &&  gpSPMSelf->pTerm
     179            &&  gpSPMSelf->pTerm->enmDeathReason == __LIBC_EXIT_REASON_NONE)
    173180        {
    174181            /* update exit code and reason. */
    175             if (gpSPMSelf->iExitCode == 0)
    176                 gpSPMSelf->iExitCode = iExitCode;
    177             if (gpSPMSelf->enmDeathReason == __LIBC_EXIT_REASON_NONE)
    178                 gpSPMSelf->enmDeathReason = enmDeathReason;
     182            gpSPMSelf->pTerm->iExitCode = iExitCode;
     183            gpSPMSelf->pTerm->enmDeathReason = enmDeathReason;
    179184        }
    180185
     
    191196
    192197/**
    193  * Gets the exit code and reason of death for a specific child process
    194  * which is believed to have died.
     198 * Query about notifications from a specific child process.
     199 * The notifications are related to death, the cause and such.
    195200 *
    196201 * @returns 0 on success.
    197202 * @returns Negative error code (errno.h) on failure.
    198203 * @param   pid                 Process id.
    199  * @param   pendDeathReason     Where to store the death reason.
    200  * @param   piExitCode          Where to store the exit code.
    201  */
    202 int __libc_spmReapChild(pid_t pid, __LIBC_EXIT_REASON *penmDeathReason, int *piExitCode)
    203 {
    204     LIBCLOG_ENTER("pid=%#x (%d) penmDeathReason=%p piExitCode=%p\n", pid, pid, (void *)penmDeathReason, (void *)piExitCode);
     204 * @param   pNotify             Where to store the notification from the child.
     205 */
     206int __libc_spmQueryChildNotification(pid_t pid, __LIBC_PSPMCHILDNOTIFY pNotifyOut)
     207{
     208    LIBCLOG_ENTER("pid=%#x (%d) pNotifyOut=%p\n", pid, pid, (void *)pNotifyOut);
    205209    __LIBC_SPMXCPTREGREC    RegRec;
    206     int                     iExitCode = 0;
    207     __LIBC_EXIT_REASON      enmDeathReason = 0;
     210    __LIBC_SPMCHILDNOTIFY   NotifyTmp = {0};
    208211
    209212    /*
     
    216219         * Try find the process, it gotta be a zombie.
    217220         */
    218         __LIBC_PSPMPROCESS pProcess = spmQueryProcessInState(pid, __LIBC_PROCSTATE_ZOMBIE);
    219         if (pProcess)
    220         {
    221             iExitCode = pProcess->iExitCode;
    222             enmDeathReason = pProcess->enmDeathReason;
    223 
    224             /* reap it */
    225             if (pProcess->cReferences > 0)
    226                 pProcess->cReferences--;
    227             if (pProcess->cReferences <= 0)
    228                 spmFreeProcess(pProcess);
    229         }
    230         else
    231             rc = -ESRCH;
     221        rc = -ESRCH;
     222        __LIBC_PSPMCHILDNOTIFY pPrev = NULL;
     223        __LIBC_PSPMCHILDNOTIFY pNotify = gpSPMSelf->pChildNotifyHead;
     224        while (pNotify)
     225        {
     226            if (pNotify->pid == pid)
     227            {
     228                /*
     229                 * Copy the data to temporary storage.
     230                 */
     231                if (pNotify->cb >= sizeof(NotifyTmp))
     232                    NotifyTmp = *pNotify;
     233                else
     234                    memcpy(&NotifyTmp, pNotify, pNotify->cb);
     235                NotifyTmp.pNext = NULL;
     236
     237                /*
     238                 * Unlink and free it.
     239                 */
     240                if (gpSPMSelf->ppChildNotifyTail == &pNotify->pNext)
     241                {
     242                    if (pPrev)
     243                        gpSPMSelf->ppChildNotifyTail = &pPrev->pNext;
     244                    else
     245                        gpSPMSelf->ppChildNotifyTail = &gpSPMSelf->pChildNotifyHead;
     246                    *gpSPMSelf->ppChildNotifyTail = NULL;
     247                }
     248                else
     249                {
     250                    if (pPrev)
     251                        pPrev->pNext = pNotify->pNext;
     252                    else
     253                        gpSPMSelf->pChildNotifyHead = pNotify->pNext;
     254                }
     255
     256                spmFreeChildNotify(pNotify);
     257                rc = 0;
     258                break;
     259            }
     260
     261            /* next */
     262            pPrev = pNotify;
     263            pNotify = pNotify->pNext;
     264        }
    232265
    233266        /*
    234          * We're done, free the mutex and store the results.
     267         * We're done, release the mutex and store the results.
    235268         */
    236269        spmReleaseMutex(&RegRec);
    237         *penmDeathReason = enmDeathReason;
    238         *piExitCode = iExitCode;
     270        *pNotify = NotifyTmp;
    239271    }
    240272
     
    274306
    275307    /*
    276      * Check if we've already registered.
     308     * Check if we've already registered (we're allways registred).
    277309     * If we have we'll simply return.
    278310     */
     
    282314    {
    283315        __LIBC_SPMXCPTREGREC    RegRec;
    284         PTIB                    pTib;
    285         PPIB                    pPib;
    286         FS_VAR()
    287         FS_SAVE_LOAD();
    288         DosGetInfoBlocks(&pTib, &pPib);
    289316        if (spmRequestMutexErrno(&RegRec))
    290317            LIBCLOG_RETURN_P(NULL);
     
    292319            pProcess = gpSPMSelf;
    293320        else
    294             pProcess = spmRegisterSelf(pPib->pib_ulpid, pPib->pib_ulppid);
     321        {
     322            PTIB                    pTib;
     323            PPIB                    pPib;
     324            PLINFOSEG               pLIS = GETLINFOSEG();
     325            FS_VAR()
     326            FS_SAVE_LOAD();
     327            DosGetInfoBlocks(&pTib, &pPib);
     328            pProcess = spmRegisterSelf(pPib->pib_ulpid, pPib->pib_ulppid, pLIS->sgCurrent);
     329            FS_RESTORE();
     330        }
    295331        spmReleaseMutex(&RegRec);
    296         FS_RESTORE();
    297332    }
    298333
     
    458493         * Initialize the new process block.
    459494         */
    460         pProcess->uVersion      = SPM_VERSION;
    461         pProcess->cReferences   = 1;
    462         pProcess->pid           = -1;
    463         pProcess->pidParent     = pidParent;
    464         pProcess->enmState      = __LIBC_PROCSTATE_EMBRYO;
    465         pProcess->uTimestamp    = spmTimestamp();
    466         pProcess->cPoolPointers = 2; /** @todo define for this! */
     495        pProcess->uVersion          = SPM_VERSION;
     496        pProcess->cReferences       = 1;
     497        pProcess->enmState          = __LIBC_PROCSTATE_EMBRYO;
     498        pProcess->pid               = -1;
     499        pProcess->pidParent         = pidParent;
     500        pProcess->uid               = gpSPMSelf->uid;
     501        pProcess->euid              = gpSPMSelf->euid;
     502        pProcess->svuid             = gpSPMSelf->svuid;
     503        pProcess->gid               = gpSPMSelf->gid;
     504        pProcess->egid              = gpSPMSelf->egid;
     505        pProcess->svgid             = gpSPMSelf->svgid;
     506        memcpy(&pProcess->agidGroups[0], &gpSPMSelf->agidGroups[0], sizeof(pProcess->agidGroups));
     507        pProcess->uTimestamp        = spmTimestamp();
     508        //pProcess->cSPMOpens         = 0;
     509        pProcess->fExeInited        = 1;
     510        //pProcess->uMiscReserved     = 0;
     511        //pProcess->pvModuleHead      = NULL;
     512        pProcess->ppvModuleTail     = &pProcess->pvModuleHead;
     513        //pProcess->pvForkHandle      = NULL;
     514        //pProcess->pSigHead          = NULL;
     515        //pProcess->cSigsSent         = 0;
     516        pProcess->sid               = gpSPMSelf->sid;
     517        pProcess->pgrp              = gpSPMSelf->pgrp;
     518        //pProcess->uSigReserved1     = 0; //gpSPMSelf->uSigReserved1;
     519        //pProcess->uSigReserved2     = 0; //gpSPMSelf->uSigReserved2;
     520        __LIBC_PSPMCHILDNOTIFY pTerm= spmAllocChildNotify();
     521        if (pTerm)
     522        {
     523            pTerm->cb               = sizeof(*pTerm);
     524            pTerm->enmDeathReason   = __LIBC_EXIT_REASON_NONE;
     525            pTerm->iExitCode        = 0;
     526            pTerm->pid              = -1;
     527            pTerm->pNext            = NULL;
     528            pProcess->pTerm         = pTerm;
     529        }
     530        //pProcess->pChildNotifyHead  = NULL;
     531        pProcess->ppChildNotifyTail = &pProcess->pChildNotifyHead;
     532        //pProcess->auReserved        = {0};
     533        pProcess->cPoolPointers     = __LIBC_SPMPROCESS_POOLPOINTERS;
     534        //pProcess->pInherit          = NULL;
     535        //pProcess->pInheritLocked    = NULL;
    467536
    468537        /* link into list. */
     
    631700
    632701/**
     702 * Gets the specified Id.
     703 *
     704 * @returns Requested Id.
     705 * @param   enmId       Identification to get.
     706 */
     707unsigned __libc_spmGetId(__LIBC_SPMID enmId)
     708{
     709    LIBCLOG_ENTER("enmId=%d\n", enmId);
     710    __LIBC_SPMXCPTREGREC    RegRec;
     711
     712    /*
     713     * Obtain semaphore.
     714     */
     715    int rc = spmRequestMutex(&RegRec);
     716    if (!rc)
     717        LIBCLOG_RETURN_INT(-1);
     718
     719    unsigned id;
     720    switch (enmId)
     721    {
     722        case __LIBC_SPMID_PID:      id = gpSPMSelf->pid; break;
     723        case __LIBC_SPMID_PPID:     id = gpSPMSelf->pidParent; break;
     724        case __LIBC_SPMID_SID:      id = gpSPMSelf->sid; break;
     725        case __LIBC_SPMID_PGRP:     id = gpSPMSelf->pgrp; break;
     726        case __LIBC_SPMID_UID:      id = gpSPMSelf->uid; break;
     727        case __LIBC_SPMID_EUID:     id = gpSPMSelf->euid; break;
     728        case __LIBC_SPMID_SVUID:    id = gpSPMSelf->svuid; break;
     729        case __LIBC_SPMID_GID:      id = gpSPMSelf->gid; break;
     730        case __LIBC_SPMID_EGID:     id = gpSPMSelf->egid; break;
     731        case __LIBC_SPMID_SVGID:    id = gpSPMSelf->svgid; break;
     732        default:
     733            id = -1;
     734            break;
     735    }
     736
     737    /*
     738     * Done.
     739     */
     740    spmReleaseMutex(&RegRec);
     741    LIBCLOG_RETURN_INT(id);
     742}
     743
     744/**
     745 * Sets the effective user id of the current process.
     746 * If the caller is superuser real and saved user id are also set.
     747 *
     748 * @returns 0 on success.
     749 * @returns Negative error code (errno) on failure.
     750 * @param   uid         New effective user id.
     751 *                      For superusers this is also the new real and saved user id.
     752 */
     753int __libc_spmSetUid(uid_t uid)
     754{
     755    LIBCLOG_ENTER("uid=%d (%#x)\n", uid, uid);
     756    __LIBC_SPMXCPTREGREC    RegRec;
     757
     758    /*
     759     * Obtain semaphore.
     760     */
     761    int rc = spmRequestMutex(&RegRec);
     762    if (!rc)
     763        LIBCLOG_RETURN_INT(rc);
     764
     765    /*
     766     * Are we supervisor?
     767     */
     768    if (!gpSPMSelf->euid)
     769    {
     770        gpSPMSelf->uid = uid;
     771        gpSPMSelf->euid = uid;
     772        gpSPMSelf->svuid = uid;
     773    }
     774    else
     775    {
     776        if (uid == gpSPMSelf->uid || uid == gpSPMSelf->svuid)
     777            gpSPMSelf->euid = uid;
     778        else
     779            rc = -EPERM;
     780    }
     781
     782    /*
     783     * Done.
     784     */
     785    spmReleaseMutex(&RegRec);
     786    LIBCLOG_RETURN_INT(rc);
     787}
     788
     789/**
     790 * Sets the real, effective and saved user ids of the current process.
     791 * Unprivilegde users can only set them to the real user id, the
     792 * effective user id or the saved user id.
     793 *
     794 * @returns 0 on success.
     795 * @returns Negative error code (errno) on failure.
     796 * @param   ruid    New real user id. Ignore if -1.
     797 * @param   euid    New effective user id. Ignore if -1.
     798 * @param   svuid   New Saved user id. Ignore if -1.
     799 */
     800int __libc_spmSetUidAll(uid_t ruid, uid_t euid, uid_t svuid)
     801{
     802    LIBCLOG_ENTER("ruid=%d (%#x) euid=%d (%#x) svuid=%d (%#x)\n", ruid, ruid, euid, euid, svuid, svuid);
     803    __LIBC_SPMXCPTREGREC    RegRec;
     804
     805    /*
     806     * Obtain semaphore.
     807     */
     808    int rc = spmRequestMutex(&RegRec);
     809    if (!rc)
     810        LIBCLOG_RETURN_INT(rc);
     811
     812    /*
     813     * Are we supervisor?
     814     */
     815    if (   !gpSPMSelf->euid
     816        || (    ( ruid == -1 ||  ruid == gpSPMSelf->uid ||  ruid == gpSPMSelf->euid ||  ruid == gpSPMSelf->svuid)
     817            &&  ( euid == -1 ||  euid == gpSPMSelf->uid ||  euid == gpSPMSelf->euid ||  euid == gpSPMSelf->svuid)
     818            &&  (svuid == -1 || svuid == gpSPMSelf->uid || svuid == gpSPMSelf->euid || svuid == gpSPMSelf->svuid)))
     819    {
     820        if (ruid != -1)
     821            gpSPMSelf->uid = ruid;
     822        if (euid != -1)
     823           gpSPMSelf->euid = euid;
     824        if (svuid != -1)
     825            gpSPMSelf->svuid = svuid;
     826    }
     827    else
     828        rc = -EPERM;
     829
     830    /*
     831     * Done.
     832     */
     833    spmReleaseMutex(&RegRec);
     834    LIBCLOG_RETURN_INT(rc);
     835}
     836
     837/**
     838 * Sets the effective group id of the current process.
     839 * If the caller is superuser real and saved group id are also set.
     840 *
     841 * @returns 0 on success.
     842 * @returns Negative error code (errno) on failure.
     843 */
     844int __libc_spmSetGid(gid_t gid)
     845{
     846    LIBCLOG_ENTER("gid=%d (%#x)\n", gid, gid);
     847    __LIBC_SPMXCPTREGREC    RegRec;
     848
     849    /*
     850     * Obtain semaphore.
     851     */
     852    int rc = spmRequestMutex(&RegRec);
     853    if (!rc)
     854        LIBCLOG_RETURN_INT(rc);
     855
     856    /*
     857     * Are we supervisor?
     858     */
     859    if (!gpSPMSelf->euid)
     860    {
     861        gpSPMSelf->gid = gid;
     862        gpSPMSelf->egid = gid;
     863        gpSPMSelf->svgid = gid;
     864    }
     865    else
     866    {
     867        if (gid == gpSPMSelf->gid || gid == gpSPMSelf->svgid)
     868            gpSPMSelf->egid = gid;
     869        else
     870            rc = -EPERM;
     871    }
     872
     873    /*
     874     * Done.
     875     */
     876    spmReleaseMutex(&RegRec);
     877    LIBCLOG_RETURN_INT(rc);
     878}
     879
     880
     881/**
     882 * Sets the real, effective and saved group ids of the current process.
     883 * Unprivilegde users can only set them to the real group id, the
     884 * effective group id or the saved group id.
     885 *
     886 * @returns 0 on success.
     887 * @returns Negative error code (errno) on failure.
     888 * @param   rgid    New real group id. Ignore if -1.
     889 * @param   egid    New effective group id. Ignore if -1.
     890 * @param   svgid   New Saved group id. Ignore if -1.
     891 */
     892int __libc_spmSetGidAll(gid_t rgid, gid_t egid, gid_t svgid)
     893{
     894    LIBCLOG_ENTER("rgid=%d (%#x) egid=%d (%#x) svgid=%d (%#x)\n", rgid, rgid, egid, egid, svgid, svgid);
     895    __LIBC_SPMXCPTREGREC    RegRec;
     896
     897    /*
     898     * Obtain semaphore.
     899     */
     900    int rc = spmRequestMutex(&RegRec);
     901    if (!rc)
     902        LIBCLOG_RETURN_INT(rc);
     903
     904    /*
     905     * Are we supervisor?
     906     */
     907    if (   !gpSPMSelf->euid
     908        || (    ( rgid == -1 ||  rgid == gpSPMSelf->gid ||  rgid == gpSPMSelf->egid ||  rgid == gpSPMSelf->svgid)
     909            &&  ( egid == -1 ||  egid == gpSPMSelf->gid ||  egid == gpSPMSelf->egid ||  egid == gpSPMSelf->svgid)
     910            &&  (svgid == -1 || svgid == gpSPMSelf->gid || svgid == gpSPMSelf->egid || svgid == gpSPMSelf->svgid)))
     911    {
     912        if (rgid != -1)
     913            gpSPMSelf->gid = rgid;
     914        if (egid != -1)
     915           gpSPMSelf->egid = egid;
     916        if (svgid != -1)
     917            gpSPMSelf->svgid = svgid;
     918    }
     919    else
     920        rc = -EPERM;
     921
     922    /*
     923     * Done.
     924     */
     925    spmReleaseMutex(&RegRec);
     926    LIBCLOG_RETURN_INT(rc);
     927}
     928
     929
     930/**
    633931 * Locks the LIBC shared memory for short exclusive access.
    634932 * The call must call __libc_spmUnlock() as fast as possible and make
     
    9401238 * @returns 0 on success.
    9411239 * @returns Negative error code (errno.h) on failure.
    942  * @param   pSignal     Signal to queue.
     1240 */
     1241void    __libc_spmExeInited(void)
     1242{
     1243    __atomic_xchg(&gpSPMSelf->fExeInited, 1);
     1244}
     1245
     1246
     1247/**
     1248 * Queues a signal on another process.
     1249 *
     1250 * @returns 0 on success.
     1251 * @returns Negative error code (errno.h) on failure.
     1252 * @param   pSigInfo    Signal to queue.
    9431253 * @param   pid         Pid to queue it on.
    9441254 * @param   fQueued     Set if the signal type is queued.
    9451255 */
    946 void    __libc_spmExeInited(void)
    947 {
    948     __atomic_xchg(&gpSPMSelf->fExeInited, 1);
    949 }
    950 
    951 
    952 /**
    953  * Queues a signal on another process.
    954  *
    955  * @returns 0 on success.
    956  * @returns Negative error code (errno.h) on failure.
    957  * @param   pSignal     Signal to queue.
    958  * @param   pid         Pid to queue it on.
    959  * @param   fQueued     Set if the signal type is queued.
    960  */
    961 int     __libc_spmSigQueue(siginfo_t *pSignal, pid_t pid, int fQueued)
    962 {
    963     LIBCLOG_ENTER("pSignal=%p:{.si_signo=%d,..} pid=%d fQueued=%d\n", (void *)pSignal, pSignal->si_signo, pid, fQueued);
     1256int     __libc_spmSigQueue(int iSignalNo, siginfo_t *pSigInfo, pid_t pid, int fQueued)
     1257{
     1258    LIBCLOG_ENTER("pSigInfo=%p:{.si_signo=%d,..} pid=%#x (%d) fQueued=%d\n", (void *)pSigInfo, pSigInfo->si_signo, pid, pid, fQueued);
    9641259
    9651260    /*
     
    9671262     * This is mostly because we wanna crash before we take the sem.
    9681263     */
    969     if (pSignal->si_signo <= 0 || pSignal->si_signo > SIGRTMAX)
    970     {
    971         LIBC_ASSERTM_FAILED("Invalid signal number %d\n", pSignal->si_signo);
     1264    if (iSignalNo < 0 || iSignalNo > SIGRTMAX)
     1265    {
     1266        LIBC_ASSERTM_FAILED("Invalid signal number %d\n", pSigInfo->si_signo);
    9721267        LIBCLOG_RETURN_INT(-EINVAL);
    9731268    }
    974     if (pSignal->auReserved[(sizeof(pSignal->auReserved) / sizeof(pSignal->auReserved[0])) - 1])
    975     {
    976         LIBC_ASSERTM_FAILED("Reserved field is not zero!\n");
    977         LIBCLOG_RETURN_INT(-EINVAL);
     1269    if (pSigInfo)
     1270    {
     1271        if (pSigInfo->si_signo != iSignalNo)
     1272        {
     1273            LIBC_ASSERTM_FAILED("Signal Number doesn't match the signal info!\n");
     1274            LIBCLOG_RETURN_INT(-EINVAL);
     1275        }
     1276        if (pSigInfo->auReserved[(sizeof(pSigInfo->auReserved) / sizeof(pSigInfo->auReserved[0])) - 1])
     1277        {
     1278            LIBC_ASSERTM_FAILED("Reserved field is not zero!\n");
     1279            LIBCLOG_RETURN_INT(-EINVAL);
     1280        }
    9781281    }
    9791282
     
    9911294    __LIBC_PSPMPROCESS pProcess = spmQueryProcessInState(pid, __LIBC_PROCSTATE_ALIVE);
    9921295    if (pProcess && pProcess->fExeInited)
    993     {
    994         /*
    995          * Check if already pending.
    996          */
    997         __LIBC_PSPMSIGNAL   pSig = NULL;
    998         if (!fQueued)
    999         {
    1000             pSig = pProcess->pSigHead;
    1001             int iSignal = pSignal->si_signo;
    1002             for (pSig = pProcess->pSigHead; pSig; pSig = pSig->pNext)
    1003                 if (pSig->Info.si_signo == iSignal)
    1004                     break;
    1005         }
    1006         if (!pSig)
    1007         {
    1008             /*
    1009              * Check that we're not exceeding any per process or system limits.
    1010              */
    1011             if (    (   gpSPMHdr->cSigActive < gpSPMHdr->cSigMaxActive
    1012                      && gpSPMSelf->cSigsSent < _POSIX_SIGQUEUE_MAX)
    1013                 || pSignal->si_signo == SIGCHLD)
     1296        rc = spmSigQueueProcess(pProcess, iSignalNo, pSigInfo, fQueued, 0);
     1297    else
     1298        rc = -ESRCH;
     1299
     1300    /*
     1301     * Release sem and be gone.
     1302     */
     1303    spmReleaseMutex(&RegRec);
     1304    LIBCLOG_RETURN_INT(rc);
     1305}
     1306
     1307/**
     1308 * Queues a signal on another process.
     1309 *
     1310 * @returns 0 on success.
     1311 * @returns Negative error code (errno.h) on failure.
     1312 * @param   iSignalNo   The signal to send. If 0 only permissions are checked.
     1313 * @param   pSigInfo     Signal to queue. If NULL only permissions are checked.
     1314 * @param   pgrp        Process group to queue a signal on.
     1315 * @param   fQueued     Set if the signal type is queued.
     1316 * @param   pfnCallback Pointer to callback function to post process signaled processes.
     1317 *                      The callback must be _very_ careful. No crashing or blocking!
     1318 * @param   pvUser      User argument specified to pfnCallback.
     1319 */
     1320int     __libc_spmSigQueuePGrp(int iSignalNo, siginfo_t *pSigInfo, pid_t pgrp, int fQueued, __LIBC_PFNSPMSIGNALED pfnCallback, void *pvUser)
     1321{
     1322    LIBCLOG_ENTER("iSignalNo=%d pSigInfo=%p:{.si_signo=%d,..} pgrp=%#x (%d) fQueued=%d pfnCallback=%p pvUser=%p\n",
     1323                  iSignalNo, (void *)pSigInfo, pSigInfo->si_signo, pgrp, pgrp, fQueued, (void *)pfnCallback, pvUser);
     1324
     1325    /*
     1326     * Validate intput.
     1327     * This is mostly because we wanna crash before we take the sem.
     1328     */
     1329    if (iSignalNo < 0 || iSignalNo > SIGRTMAX)
     1330    {
     1331        LIBC_ASSERTM_FAILED("Invalid signal number %d\n", pSigInfo->si_signo);
     1332        LIBCLOG_RETURN_INT(-EINVAL);
     1333    }
     1334    if (pSigInfo)
     1335    {
     1336        if (pSigInfo->si_signo != iSignalNo)
     1337        {
     1338            LIBC_ASSERTM_FAILED("Signal Number doesn't match the signal info!\n");
     1339            LIBCLOG_RETURN_INT(-EINVAL);
     1340        }
     1341        if (pSigInfo->auReserved[(sizeof(pSigInfo->auReserved) / sizeof(pSigInfo->auReserved[0])) - 1])
     1342        {
     1343            LIBC_ASSERTM_FAILED("Reserved field is not zero!\n");
     1344            LIBCLOG_RETURN_INT(-EINVAL);
     1345        }
     1346    }
     1347
     1348    /*
     1349     * Request sem.
     1350     */
     1351    __LIBC_SPMXCPTREGREC    RegRec;
     1352    int rc = spmRequestMutex(&RegRec);
     1353    if (rc)
     1354        LIBCLOG_RETURN_INT(rc);
     1355
     1356    /*
     1357     * Signal this process group?
     1358     */
     1359    if (!pgrp)
     1360        pgrp = gpSPMSelf->pgrp;
     1361    if (pgrp == gpSPMSelf->pgrp)
     1362        LIBCLOG_MSG("Signalling our own process group, %#x (%d).\n", pgrp, pgrp);
     1363
     1364    /*
     1365     * Enumerate all alive processes and process the processes in the specified group.
     1366     */
     1367    unsigned            cSent = 0;
     1368    __LIBC_PSPMPROCESS  pProcess = gpSPMHdr->apHeads[__LIBC_PROCSTATE_ALIVE];
     1369    for (; pProcess; pProcess = pProcess->pNext)
     1370    {
     1371        if (    pProcess->pgrp != pgrp
     1372            && !pProcess->fExeInited)
     1373        {
     1374            /* try queue the signal */
     1375            int rc2 = spmSigQueueProcess(pProcess, iSignalNo, pSigInfo, fQueued, 1 /* send anyway */);
     1376            if (!rc2)
    10141377            {
    1015                 /*
    1016                  * Allocate a signal packet.
    1017                  */
    1018                 if (gpSPMHdr->pSigFreeHead)
     1378                cSent++;
     1379                if (pfnCallback)
    10191380                {
    1020                     __LIBC_PSPMSIGNAL pPrev = NULL;
    1021                     for (pSig = gpSPMHdr->pSigFreeHead; pSig; pPrev = pSig, pSig = pSig->pNext)
    1022                     {
    1023                         if (pSig->cb == sizeof(*pSig))
    1024                         {
    1025                             if (pPrev)
    1026                                 pPrev->pNext = pSig->pNext;
    1027                             else
    1028                                 gpSPMHdr->pSigFreeHead = pSig->pNext;
    1029                             gpSPMHdr->cSigFree--;
    1030                             break;
    1031                         }
    1032                     }
    1033                 }
    1034                 if (!pSig)
    1035                 {
    1036                     pSig = spmAlloc(sizeof(*pSig));
    1037                     if (pSig)
    1038                         pSig->cb = sizeof(*pSig);
    1039                 }
    1040 
    1041                 /*
    1042                  * Copy the data and insert it into the queue.
    1043                  */
    1044                 if (pSig)
    1045                 {
    1046                     pSig->pNext     = NULL;
    1047                     pSig->pidSender = gpSPMSelf->pid;
    1048                     pSig->Info      = *pSignal;
    1049                     if (fQueued)
    1050                         pSig->Info.si_flags |= __LIBC_SI_QUEUED;
    1051                     else
    1052                         pSig->Info.si_flags &= ~__LIBC_SI_QUEUED;
    1053 
    1054                     /* insert (FIFO) */
    1055                     if (!pProcess->pSigHead)
    1056                         pProcess->pSigHead = pSig;
    1057                     else
    1058                     {
    1059                         __LIBC_PSPMSIGNAL pSigLast = pProcess->pSigHead;
    1060                         while (pSigLast->pNext)
    1061                             pSigLast = pSigLast->pNext;
    1062                         pSigLast->pNext = pSig;
    1063                     }
    1064 
    1065                     /* update statistics */
    1066                     if (pProcess != gpSPMSelf)
    1067                         gpSPMSelf->cSigsSent++;
    1068                     gpSPMHdr->cSigActive++;
    1069                 }
    1070                 else
    1071                 {
    1072                     LIBCLOG_MSG("Out of memory! Cannot allocate %d bytes for a signal packet!\n", sizeof(*pSig));
    1073                     rc = -EAGAIN;
     1381                    /* callback the caller. */
     1382                    rc2 = pfnCallback(iSignalNo, pProcess, pvUser);
     1383                    if (rc2 < 0 && !rc)
     1384                        rc = rc2;
    10741385                }
    10751386            }
    1076             else
    1077             {
    1078                 LIBCLOG_MSG("Limit reached: cSigActive=%d cSigMaxActive=%d cSigsSent=%d (max %d)\n",
    1079                             gpSPMHdr->cSigActive, gpSPMHdr->cSigMaxActive, pProcess->cSigsSent, _POSIX_SIGQUEUE_MAX);
    1080                 rc = -EAGAIN;
    1081             }
    1082         }
    1083         else
    1084             LIBCLOG_MSG("Signal %d is already pending on pid %d. (ts=%x,pid=%d)\n",
    1085                         pSignal->si_signo, pid, pSig->Info.si_timestamp, pSig->Info.si_pid);
    1086     }
    1087     else
    1088         rc = -ESRCH;
     1387            else if (!rc)
     1388                rc = rc2;
     1389        }
     1390    } /* for each alive process. */
     1391
     1392    /*
     1393     * Adjust error codes.
     1394     */
     1395    if (!rc)
     1396    {
     1397        if (!cSent)
     1398            rc = -ESRCH;
     1399    }
     1400    else if (rc == -EPERM && cSent > 0)
     1401        rc = 0;
    10891402
    10901403    /*
     
    10941407    LIBCLOG_RETURN_INT(rc);
    10951408}
     1409
    10961410
    10971411/**
     
    12161530
    12171531        /* free */
    1218         if (gpSPMHdr->cSigFree < 32)
    1219         {
    1220             pSig->pNext = gpSPMHdr->pSigFreeHead;
    1221             gpSPMHdr->pSigFreeHead = pSig;
    1222             gpSPMHdr->cSigFree++;
    1223         }
    1224         else
    1225             spmFree(pSig);
     1532        spmFreeSignal(pSig);
    12261533
    12271534        /*
     
    12361543    LIBCLOG_RETURN_INT(rc);
    12371544}
    1238 
    12391545
    12401546
     
    13221628            DosGetInfoBlocks(&pTib, &pPib);
    13231629            gpSPMSelf = __libc_spmQueryProcessInState(pPib->pib_ulpid, __LIBC_PROCSTATE_ALIVE);
    1324             LIBC_ASSERTM(gpSPMSelf, "Couldn't find our self after fork - impossibled! pid=%ld ppid=%ld\n", pPib->pib_ulpid, pPib->pib_ulppid);
     1630            LIBC_ASSERTM(gpSPMSelf, "Couldn't find our self after fork - impossibled! pid=%lx (%ld) ppid=%lx (%ld)\n",
     1631                         pPib->pib_ulpid, pPib->pib_ulpid, pPib->pib_ulppid, pPib->pib_ulppid);
    13251632            LIBC_ASSERTM(gpSPMSelf->cReferences >= 2, "cReferences=%d!\n", gpSPMSelf->cReferences);
    13261633            gpSPMSelf->cReferences--;
     
    13641671 * stack available. If there isn't a crash is usually the
    13651672 * result.
     1673 * @internal
    13661674 */
    13671675static int spmRequestMutexStackChecker(void)
    13681676{
    1369     char *pch = alloca(2048);
     1677    char volatile *pch = alloca(2048);
    13701678    if (!pch)
    13711679        return -1;
     
    13781686 * Requests the shared mutex semphore and checks that we're
    13791687 * successfully initialized.
    1380  * @internal
    13811688 * @returns 0 on success.
    13821689 * @returns Negative error code (errno.h) on failure.
     1690 * @internal
    13831691 */
    13841692static int spmRequestMutex(__LIBC_PSPMXCPTREGREC pRegRec)
     
    14901798}
    14911799
     1800#if 0 /* unused */
     1801/**
     1802 * Checks if the caller is the mutex owner.
     1803 * @returns 0 if not owner.
     1804 * @returns 1 if owner.
     1805 */
     1806static int spmIsMutexOwner(void)
     1807{
     1808    if (gcNesting != 1)
     1809        return 0;
     1810
     1811    PTIB pTib;
     1812    PPIB pPib;
     1813    DosGetInfoBlocks(&pTib, &pPib);
     1814    PID pid;
     1815    TID tid;
     1816    ULONG cNestings = 0;
     1817    int rc = DosQueryMutexSem(ghmtxSPM, &pid, &tid, &cNestings);
     1818    return !rc && pid == pPib->pib_ulpid && tid == pTib->tib_ptib2->tib2_ultid;
     1819}
     1820#endif /* unused */
    14921821
    14931822/**
     
    15111840     */
    15121841    LIBC_ASSERT(sizeof(*gpSPMHdr) < SPM_PROCESS_SIZE);
    1513     LIBC_ASSERT(offsetof(__LIBC_SPMHEADER, pTcpip) == 72);
    1514     LIBC_ASSERT(offsetof(__LIBC_SPMHEADER, cSigMaxActive) == 124);
     1842    LIBC_ASSERT(offsetof(__LIBC_SPMHEADER, pTcpip) == 56);
     1843    LIBC_ASSERT(offsetof(__LIBC_SPMHEADER, pChildNotifyFreeHead) == 52);
     1844    LIBC_ASSERT(offsetof(__LIBC_SPMHEADER, hevNotify) == 112);
     1845    LIBC_ASSERT(offsetof(__LIBC_SPMHEADER, cSigMaxActive) == 108);
    15151846    LIBC_ASSERT(offsetof(__LIBC_SPMPROCESS, cReferences) == 12);
    1516     LIBC_ASSERT(offsetof(__LIBC_SPMPROCESS, pvForkHandle) == 48);
    1517     LIBC_ASSERT(offsetof(__LIBC_SPMPROCESS, cPoolPointers) == 160);
    1518     LIBC_ASSERT(offsetof(__LIBC_SPMPROCESS, pInheritLocked) == 168);
     1847    LIBC_ASSERT(offsetof(__LIBC_SPMPROCESS, pvForkHandle) == 140);
     1848    LIBC_ASSERT(offsetof(__LIBC_SPMPROCESS, cPoolPointers) == 224);
     1849    LIBC_ASSERT(offsetof(__LIBC_SPMPROCESS, pInheritLocked) == 232);
    15191850
    15201851    /*
     
    16261957                    gpSPMHdr->pSigFreeHead = pSignal;
    16271958                }
     1959                /* Create notification semaphore. */
     1960                rc = DosCreateEventSem(NULL, &gpSPMHdr->hevNotify, DC_SEM_SHARED, FALSE);
     1961                LIBC_ASSERTM(!rc, "DosCreateEventSem rc=%d\n", rc);
     1962                rc = 0; /* ignore */
    16281963            }
    16291964        }
     
    16351970             * Register the current process and increment open counter.
    16361971             */
    1637             spmRegisterSelf(pPib->pib_ulpid, pPib->pib_ulppid);
     1972            PLINFOSEG pLIS = GETLINFOSEG();
     1973            spmRegisterSelf(pPib->pib_ulpid, pPib->pib_ulppid, pLIS->sgCurrent);
    16381974            if (gpSPMSelf)
    16391975                gpSPMSelf->cSPMOpens++;
     
    17512087        {
    17522088            /* sanity */
    1753             LIBC_ASSERTM(pProcess->enmState == __LIBC_PROCSTATE_EMBRYO, "Found non embryo process in embryo list! enmState=%d pid=%d\n",
    1754                          pProcess->enmState, pProcess->pid);
    1755             LIBC_ASSERTM(pProcess->cReferences <= 1, "Invalid reference count of a process in the embryo list! cReferences=%d pid=%d\n",
    1756                          pProcess->cReferences, pProcess->pid);
     2089            LIBC_ASSERTM(pProcess->enmState == __LIBC_PROCSTATE_EMBRYO, "Found non embryo process in embryo list! enmState=%d pid=%#x (%d)\n",
     2090                         pProcess->enmState, pProcess->pid, pProcess->pid);
     2091            LIBC_ASSERTM(pProcess->cReferences <= 1, "Invalid reference count of a process in the embryo list! cReferences=%d pid=%#x (%d)\n",
     2092                         pProcess->cReferences, pProcess->pid, pProcess->pid);
    17572093
    17582094            /* our child? */
     
    17922128                pProcess->cSPMOpens--;
    17932129
     2130            /*
     2131             * if we have a child termination notification structure we'll
     2132             * send that to the parent (if we have one).
     2133             */
     2134            __LIBC_PSPMCHILDNOTIFY pTerm = pProcess->pTerm;
     2135            if (pTerm)
     2136            {
     2137                __LIBC_PSPMPROCESS pParent = spmQueryProcessInState(pProcess->pidParent, __LIBC_PROCSTATE_ALIVE);
     2138                if (pParent)
     2139                {
     2140                    *pParent->ppChildNotifyTail = pTerm;
     2141                    pParent->ppChildNotifyTail = &pTerm->pNext;
     2142                    pTerm->pNext = NULL;
     2143                    DosPostEventSem(gpSPMHdr->hevNotify);
     2144                }
     2145                else
     2146                    spmFreeChildNotify(pTerm);
     2147                pProcess->pTerm = NULL;
     2148            }
     2149
    17942150            /* free our selves or become a zombie. */
    17952151            spmZombieOrFree(pProcess);
     
    18392195    else if (pProcess->enmState != __LIBC_PROCSTATE_ZOMBIE)
    18402196    {
    1841         LIBCLOG_MSG("Making process %p a zombie (pid=%04x pidParent=%04x cReferences=%d enmState=%d)\n",
    1842                     (void *)pProcess, pProcess->pid, pProcess->pidParent, pProcess->cReferences, pProcess->enmState);
    1843 
    1844         /* free data a zombie won't be needing. */
     2197        LIBCLOG_MSG("Making process %p a zombie (pid=%#x (%d) pidParent=%#x (%d) cReferences=%d enmState=%d)\n",
     2198                    (void *)pProcess, pProcess->pid, pProcess->pid, pProcess->pidParent, pProcess->pidParent,
     2199                    pProcess->cReferences, pProcess->enmState);
     2200
     2201        /*
     2202         * Free data a zombie won't be needing.
     2203         */
     2204        /* inherited data */
    18452205        if (pProcess->pInherit)
    18462206        {
    18472207            spmFree(pProcess->pInherit);
    18482208            pProcess->pInherit = NULL;
     2209        }
     2210
     2211        /* signals */
     2212        __LIBC_PSPMSIGNAL pSig = pProcess->pSigHead;
     2213        pProcess->pSigHead = NULL;
     2214        while (pSig)
     2215        {
     2216            __LIBC_PSPMSIGNAL pFree = pSig;
     2217            pSig = pSig->pNext;
     2218            spmFreeSignal(pFree);
     2219        }
     2220
     2221        /* child notifications. */
     2222        __LIBC_PSPMCHILDNOTIFY pNotify = pProcess->pChildNotifyHead;
     2223        pProcess->pChildNotifyHead = NULL;
     2224        while (pNotify)
     2225        {
     2226            __LIBC_PSPMCHILDNOTIFY pFree = pNotify;
     2227            pNotify = pNotify->pNext;
     2228            spmFreeChildNotify(pFree);
    18492229        }
    18502230
     
    18812261static __LIBC_PSPMPROCESS spmQueryProcessInState(pid_t pid, __LIBC_SPMPROCSTAT enmState)
    18822262{
    1883     LIBCLOG_ENTER("pid=%d enmState=%d\n", pid, enmState);
     2263    LIBCLOG_ENTER("pid=%#x (%d) enmState=%d\n", pid, pid, enmState);
    18842264    __LIBC_PSPMPROCESS      pProcess;
    18852265
     
    19232303 * @param   pid         Pid of this process.
    19242304 * @param   pidParent   Pid of parent process.
    1925  */
    1926 static __LIBC_PSPMPROCESS spmRegisterSelf(pid_t pid, pid_t pidParent)
    1927 {
    1928     LIBCLOG_ENTER("pid=%d pidParent=%d\n", pid, pidParent);
     2305 * @param   sid         Session Id.
     2306 */
     2307static __LIBC_PSPMPROCESS spmRegisterSelf(pid_t pid, pid_t pidParent, pid_t sid)
     2308{
     2309    LIBCLOG_ENTER("pid=%#x (%d) pidParent=%#x (%d) sid=%#x (%d)\n", pid, pid, pidParent, pidParent, sid, sid);
    19292310    __LIBC_PSPMPROCESS pProcess;
    19302311    __LIBC_PSPMPROCESS pProcessBest;
     
    19442325        LIBC_ASSERTM((uintptr_t)pProcess - (uintptr_t)gpSPMHdr < gpSPMHdr->cb,
    19452326                     "Invalid pointer %p in EMBRYO list\n", (void *)pProcess);
    1946         LIBC_ASSERTM(pProcess->enmState == __LIBC_PROCSTATE_EMBRYO, "Found non embryo process in embryo list! enmState=%d pid=%d\n",
    1947                      pProcess->enmState, pProcess->pid);
    1948         LIBC_ASSERTM(pProcess->cReferences <= 1, "Invalid reference count of a process in the embryo list! cReferences=%d pid=%d\n",
    1949                      pProcess->cReferences, pProcess->pid);
     2327        LIBC_ASSERTM(pProcess->enmState == __LIBC_PROCSTATE_EMBRYO, "Found non embryo process in embryo list! enmState=%d pid=%#x (%d)\n",
     2328                     pProcess->enmState, pProcess->pid, pProcess->pid);
     2329        LIBC_ASSERTM(pProcess->cReferences <= 1, "Invalid reference count of a process in the embryo list! cReferences=%d pid=%#x (%d)\n",
     2330                     pProcess->cReferences, pProcess->pid, pProcess->pid);
    19502331
    19512332        /* our daddy? daddy updated it with our pid? */
     
    19672348            ||  pProcess->pNext == pProcess)
    19682349        {
    1969             LIBC_ASSERTM(pProcess->pNext != gpSPMHdr->apHeads[__LIBC_PROCSTATE_EMBRYO], "Circular list! pid=%d\n", pProcess->pid);
    1970             LIBC_ASSERTM(pProcess->pNext != pProcess, "Circular list with self! pid=%d\n", pProcess->pid);
     2350            LIBC_ASSERTM(pProcess->pNext != gpSPMHdr->apHeads[__LIBC_PROCSTATE_EMBRYO], "Circular list! pid=%#x (%d)\n", pProcess->pid, pProcess->pid);
     2351            LIBC_ASSERTM(pProcess->pNext != pProcess, "Circular list with self! pid=%#x (%d)\n", pProcess->pid, pProcess->pid);
    19712352            pProcess->pNext = NULL;
    19722353        }
     
    19762357    {
    19772358        pProcess = pProcessBest;
    1978         LIBCLOG_MSG("Found my embryo %p (pidParent=%04x pid=%04x cReferences=%d uTimestamp=%04x)\n",
     2359        LIBCLOG_MSG("Found my embryo %p (pidParent=%#x pid=%#x cReferences=%d uTimestamp=%04x)\n",
    19792360                    (void *)pProcess, pProcess->pidParent, pProcess->pid, pProcess->cReferences, pProcess->uTimestamp);
    19802361
     
    19822363        pProcess->cReferences++;
    19832364        pProcess->pid = pid;
    1984 
    1985         /* link out. */
     2365        pProcess->sid = sid;
     2366
     2367        /* unlink. */
    19862368        if (pProcess->pNext)
    19872369            pProcess->pNext->pPrev = pProcess->pPrev;
     
    20132395        LIBC_ASSERTM((uintptr_t)pProcess - (uintptr_t)gpSPMHdr < gpSPMHdr->cb,
    20142396                     "Invalid pointer %p in ALIVE list\n", (void *)pProcess);
    2015         LIBC_ASSERTM(pProcess->enmState == __LIBC_PROCSTATE_ALIVE, "Found non alive process in alive list! enmState=%d pid=%d\n",
    2016                      pProcess->enmState, pProcess->pid);
    2017 
    2018         /* is this me? */
     2397        LIBC_ASSERTM(pProcess->enmState == __LIBC_PROCSTATE_ALIVE, "Found non alive process in alive list! enmState=%d pid=%#x (%d)\n",
     2398                     pProcess->enmState, pProcess->pid, pProcess->pid);
     2399
     2400        /* is this really me? */
    20192401        if (    pProcess->pid == pid
    20202402            &&  pProcess->pidParent == pidParent)
     
    20322414            ||  pProcess->pNext == pProcess)
    20332415        {
    2034             LIBC_ASSERTM(pProcess->pNext != gpSPMHdr->apHeads[__LIBC_PROCSTATE_ALIVE], "Circular list! pid=%d\n", pProcess->pid);
    2035             LIBC_ASSERTM(pProcess->pNext != pProcess, "Circular list with self! pid=%d\n", pProcess->pid);
     2416            LIBC_ASSERTM(pProcess->pNext != gpSPMHdr->apHeads[__LIBC_PROCSTATE_ALIVE], "Circular list! pid=%#x (%d)\n", pProcess->pid, pProcess->pid);
     2417            LIBC_ASSERTM(pProcess->pNext != pProcess, "Circular list with self! pid=%#x (%d)\n", pProcess->pid, pProcess->pid);
    20362418            pProcess->pNext = NULL;
    20372419        }
     
    20472429         * Initialize the new process block.
    20482430         */
    2049         pProcess->uVersion      = SPM_VERSION;
    2050         pProcess->cReferences   = 1;
    2051         pProcess->pid           = pid;
    2052         pProcess->pidParent     = pidParent;
    2053         pProcess->enmState      = __LIBC_PROCSTATE_ALIVE;
    2054         pProcess->uTimestamp    = spmTimestamp();
    2055         pProcess->cPoolPointers = 2; /** @todo define for this! */
     2431        pProcess->uVersion          = SPM_VERSION;
     2432        pProcess->cReferences       = 1;
     2433        pProcess->enmState          = __LIBC_PROCSTATE_EMBRYO;
     2434        pProcess->pid               = pid;
     2435        pProcess->pidParent         = pidParent;
     2436        //pProcess->uid               = 0;
     2437        //pProcess->euid              = 0;
     2438        //pProcess->svuid             = 0;
     2439        //pProcess->gid               = 0;
     2440        //pProcess->egid              = 0;
     2441        //pProcess->svgid             = 0;
     2442        //bzero(&pProcess->agidGroups[0], sizeof(pProcess->agidGroups));
     2443        pProcess->uTimestamp        = spmTimestamp();
     2444        //pProcess->cSPMOpens         = 0;
     2445        pProcess->fExeInited        = 1;
     2446        //pProcess->uMiscReserved     = 0;
     2447        //pProcess->pvModuleHead      = NULL;
     2448        pProcess->ppvModuleTail     = &pProcess->pvModuleHead;
     2449        //pProcess->pvForkHandle      = NULL;
     2450        //pProcess->pSigHead          = NULL;
     2451        //pProcess->cSigsSent         = 0;
     2452        pProcess->sid               = sid;
     2453        pProcess->pgrp              = pid;
     2454        //pProcess->uSigReserved1     = 0; //gpSPMSelf->uSigReserved1;
     2455        //pProcess->uSigReserved2     = 0; //gpSPMSelf->uSigReserved2;
     2456        __LIBC_PSPMCHILDNOTIFY pTerm= spmAllocChildNotify();
     2457        if (pTerm)
     2458        {
     2459            pTerm->cb               = sizeof(*pTerm);
     2460            pTerm->enmDeathReason   = __LIBC_EXIT_REASON_NONE;
     2461            pTerm->iExitCode        = 0;
     2462            pTerm->pid              = pid;
     2463            pTerm->pNext            = NULL;
     2464            pProcess->pTerm         = pTerm;
     2465        }
     2466        //pProcess->pChildNotifyHead  = NULL;
     2467        pProcess->ppChildNotifyTail = &pProcess->pChildNotifyHead;
     2468        //pProcess->auReserved        = {0};
     2469        pProcess->cPoolPointers     = __LIBC_SPMPROCESS_POOLPOINTERS;
     2470        //pProcess->pInherit          = NULL;
     2471        //pProcess->pInheritLocked    = NULL;
    20562472
    20572473        /* link into list. */
     
    21072523            else
    21082524                gpSPMHdr->apHeads[__LIBC_PROCSTATE_ZOMBIE] = NULL;
    2109             LIBCLOG_MSG("Reaping zombie %p (pid=%04x pidParent=%04x cRefrences=%d)\n",
     2525            LIBCLOG_MSG("Reaping zombie %p (pid=%#x pidParent=%#x cRefrences=%d)\n",
    21102526                        (void *)pProcess, pProcess->pid, pProcess->pidParent, pProcess->cReferences);
    21112527        }
     
    21242540static void spmFreeProcess(__LIBC_PSPMPROCESS pProcess)
    21252541{
    2126     LIBCLOG_ENTER("pProcess=%p:{pid=%04x pidParent=%04x cReferences=%d enmState=%d pvForkHandle=%p pNext=%p pPrev=%p}\n",
     2542    LIBCLOG_ENTER("pProcess=%p:{pid=%#x pidParent=%#x cReferences=%d enmState=%d pvForkHandle=%p pNext=%p pPrev=%p}\n",
    21272543                  (void *)pProcess, pProcess->pid, pProcess->pidParent, pProcess->cReferences, pProcess->enmState,
    21282544                  pProcess->pvForkHandle, (void *)pProcess->pNext, (void *)pProcess->pPrev);
     2545    /*
     2546     * Free signals.
     2547     */
     2548    __LIBC_PSPMSIGNAL pSig = pProcess->pSigHead;
     2549    pProcess->pSigHead = NULL;
     2550    while (pSig)
     2551    {
     2552        __LIBC_PSPMSIGNAL pFree = pSig;
     2553        pSig = pSig->pNext;
     2554        spmFreeSignal(pFree);
     2555    }
     2556
     2557    /*
     2558     * Free child notifications.
     2559     */
     2560    __LIBC_PSPMCHILDNOTIFY pNotify = pProcess->pChildNotifyHead;
     2561    pProcess->pChildNotifyHead = NULL;
     2562    while (pNotify)
     2563    {
     2564        __LIBC_PSPMCHILDNOTIFY pFree = pNotify;
     2565        pNotify = pNotify->pNext;
     2566        spmFreeChildNotify(pFree);
     2567    }
    21292568
    21302569    /*
     
    21682607
    21692608/**
     2609 * Allocate a suicide note, erm, child termination notification.
     2610 *
     2611 * @returns Pointer to allocated notifcation struct. The cb member is filled in.
     2612 * @returns NULL on failure.
     2613 */
     2614static __LIBC_PSPMCHILDNOTIFY spmAllocChildNotify(void)
     2615{
     2616    LIBCLOG_ENTER("\n");
     2617
     2618    /*
     2619     * Search the free list for a node of matching size.
     2620     */
     2621    __LIBC_PSPMCHILDNOTIFY pPrev = NULL;
     2622    __LIBC_PSPMCHILDNOTIFY pNotify = gpSPMHdr->pChildNotifyFreeHead;
     2623    while (pNotify)
     2624    {
     2625        if (pNotify->cb == sizeof(*pNotify))
     2626        {
     2627            /* unlink and return. */
     2628            if (pPrev)
     2629                pPrev->pNext = pNotify->pNext;
     2630            else
     2631                gpSPMHdr->pChildNotifyFreeHead = pNotify->pNext;
     2632            pNotify->pNext = NULL;
     2633            LIBCLOG_RETURN_P(pNotify);
     2634        }
     2635    }
     2636
     2637    /*
     2638     * Restore to allocating one from the pool.
     2639     */
     2640    pNotify = spmAlloc(sizeof(*pNotify));
     2641    if (pNotify)
     2642    {
     2643        pNotify->pNext = NULL;
     2644        pNotify->cb = sizeof(*pNotify);
     2645    }
     2646
     2647    LIBCLOG_RETURN_P(pNotify);
     2648}
     2649
     2650
     2651/**
     2652 * Free a child (termination) notification.
     2653 *
     2654 * @param pNotify       The notification structure to free.
     2655 */
     2656static void spmFreeChildNotify(__LIBC_PSPMCHILDNOTIFY pNotify)
     2657{
     2658    LIBCLOG_ENTER("pNotify=%p\n", (void *)pNotify);
     2659    pNotify->pNext = gpSPMHdr->pChildNotifyFreeHead;
     2660    gpSPMHdr->pChildNotifyFreeHead = pNotify;
     2661    LIBCLOG_RETURN_VOID();
     2662}
     2663
     2664
     2665/**
     2666 * Queues a signal on a process.
     2667 *
     2668 * @returns 0 on success.
     2669 * @returns Negative error code (errno.h) on failure.
     2670 * @param   pProcess        Process to queue the signal on.
     2671 * @param   iSignalNo       Signal to send. If 0 only permission checks are performed.
     2672 * @param   pSigInfo         Signal to queue. If NULL only permission checks are performed.
     2673 * @param   fQueued         Set if the signal type is queued.
     2674 * @param   fQueueAnyway    If set the normal signal limits are bypassed.
     2675 */
     2676static int spmSigQueueProcess(__LIBC_PSPMPROCESS pProcess, int iSignalNo, siginfo_t *pSigInfo, int fQueued, int fQueueAnyway)
     2677{
     2678    LIBCLOG_ENTER("pProcess=%p {.pid=%#x, .pgrp=%#x, .sid=%#x,...} iSignalNo=%d pSigInfo=%p fQueue=%d fQueueAnyway=%d\n",
     2679                  (void *)pProcess, pProcess->pid, pProcess->pgrp, pProcess->sid, iSignalNo, (void *)pSigInfo, fQueued, fQueueAnyway);
     2680
     2681    /*
     2682     * Check permissions.
     2683     * (This is close, but not quite it.)
     2684     */
     2685    if (    pProcess != gpSPMSelf                                                   /* our selves are ok. */
     2686        &&  pProcess->euid != 0                                                     /* Root can do anything. */
     2687        &&  (iSignalNo != SIGCONT || pProcess->sid != gpSPMSelf->sid)               /* SIGCONT to everyone in the session. */
     2688        &&  pProcess->uid != gpSPMSelf->euid && pProcess->svuid != gpSPMSelf->euid  /* Same as our efficient uid is ok. */
     2689        &&  pProcess->uid != gpSPMSelf->uid  && pProcess->svuid != gpSPMSelf->uid   /* Same as our uid is ok. */
     2690        )
     2691        return -EPERM;
     2692
     2693    /* This could be a permission check call, if so, we're done now. */
     2694    if (!pSigInfo || !iSignalNo)
     2695        return 0;
     2696
     2697    /*
     2698     * Check if already pending.
     2699     */
     2700    __LIBC_PSPMSIGNAL   pSig = NULL;
     2701    if (!fQueued)
     2702    {
     2703        pSig = pProcess->pSigHead;
     2704        int iSignal = pSigInfo->si_signo;
     2705        for (pSig = pProcess->pSigHead; pSig; pSig = pSig->pNext)
     2706            if (pSig->Info.si_signo == iSignal)
     2707                break;
     2708    }
     2709    int rc = 0;
     2710    if (!pSig)
     2711    {
     2712        /*
     2713         * Check that we're not exceeding any per process or system limits (unless told to do so).
     2714         */
     2715        if (    (   gpSPMHdr->cSigActive < gpSPMHdr->cSigMaxActive
     2716                 && gpSPMSelf->cSigsSent < _POSIX_SIGQUEUE_MAX)
     2717            || fQueueAnyway
     2718            || pSigInfo->si_signo == SIGCHLD)
     2719        {
     2720            /*
     2721             * Allocate a signal packet.
     2722             */
     2723            pSig = spmAllocSignal();
     2724            if (pSig)
     2725            {
     2726                /*
     2727                 * Copy the data and insert it into the queue.
     2728                 */
     2729                pSig->pNext     = NULL;
     2730                pSig->pidSender = gpSPMSelf->pid;
     2731                pSig->Info      = *pSigInfo;
     2732                if (fQueued)
     2733                    pSig->Info.si_flags |= __LIBC_SI_QUEUED;
     2734                else
     2735                    pSig->Info.si_flags &= ~__LIBC_SI_QUEUED;
     2736
     2737                /* insert (FIFO) */
     2738                if (!pProcess->pSigHead)
     2739                    pProcess->pSigHead = pSig;
     2740                else
     2741                {
     2742                    __LIBC_PSPMSIGNAL pSigLast = pProcess->pSigHead;
     2743                    while (pSigLast->pNext)
     2744                        pSigLast = pSigLast->pNext;
     2745                    pSigLast->pNext = pSig;
     2746                }
     2747
     2748                /* update statistics */
     2749                if (pProcess != gpSPMSelf)
     2750                    gpSPMSelf->cSigsSent++;
     2751                gpSPMHdr->cSigActive++;
     2752            }
     2753            else
     2754            {
     2755                LIBCLOG_MSG("Out of memory! Cannot allocate %d bytes for a signal packet!\n", sizeof(*pSig));
     2756                rc = -EAGAIN;
     2757            }
     2758        }
     2759        else
     2760        {
     2761            LIBCLOG_MSG("Limit reached: cSigActive=%d cSigMaxActive=%d cSigsSent=%d (max %d)\n",
     2762                        gpSPMHdr->cSigActive, gpSPMHdr->cSigMaxActive, pProcess->cSigsSent, _POSIX_SIGQUEUE_MAX);
     2763            rc = -EAGAIN;
     2764        }
     2765    }
     2766    else
     2767        LIBCLOG_MSG("Signal %d is already pending on pid %#x (%d). (ts=%x,pid=%#x (%d))\n",
     2768                    pSigInfo->si_signo, pProcess->pid, pProcess->pid, pSig->Info.si_timestamp, pSig->Info.si_pid, pSig->Info.si_pid);
     2769    return rc;
     2770}
     2771
     2772
     2773/**
     2774 * Allocates a signal structure.
     2775 *
     2776 * @returns Pointer to allocated signal structure.
     2777 * @returns NULL on failure.
     2778 */
     2779static __LIBC_PSPMSIGNAL spmAllocSignal(void)
     2780{
     2781    LIBCLOG_ENTER("\n");
     2782
     2783    /*
     2784     * Old structures.
     2785     */
     2786    __LIBC_PSPMSIGNAL pSig;
     2787    if (gpSPMHdr->pSigFreeHead)
     2788    {
     2789        __LIBC_PSPMSIGNAL pPrev = NULL;
     2790        for (pSig = gpSPMHdr->pSigFreeHead; pSig; pPrev = pSig, pSig = pSig->pNext)
     2791        {
     2792            if (pSig->cb == sizeof(*pSig))
     2793            {
     2794                if (pPrev)
     2795                    pPrev->pNext = pSig->pNext;
     2796                else
     2797                    gpSPMHdr->pSigFreeHead = pSig->pNext;
     2798                gpSPMHdr->cSigFree--;
     2799                LIBCLOG_RETURN_P(pSig);
     2800            }
     2801        }
     2802    }
     2803
     2804    /*
     2805     * New structure.
     2806     */
     2807    pSig = spmAlloc(sizeof(*pSig));
     2808    if (pSig)
     2809        pSig->cb = sizeof(*pSig);
     2810
     2811    LIBCLOG_RETURN_P(pSig);
     2812}
     2813
     2814
     2815/**
     2816 * Frees a signal
     2817 *
     2818 * @param   pSig        Signal structure to free.
     2819 */
     2820static void spmFreeSignal(__LIBC_PSPMSIGNAL pSig)
     2821{
     2822    LIBCLOG_ENTER("pSig=%p\n", (void *)pSig);
     2823    if (gpSPMHdr->cSigFree < 32)
     2824    {
     2825        pSig->pNext = gpSPMHdr->pSigFreeHead;
     2826        gpSPMHdr->pSigFreeHead = pSig;
     2827        gpSPMHdr->cSigFree++;
     2828    }
     2829    else
     2830        spmFree(pSig);
     2831    LIBCLOG_RETURN_VOID();
     2832}
     2833
     2834
     2835/**
    21702836 * Allocate memory in SPM pool of given size.
    21712837 *
     
    22072873
    22082874        /*
    2209          * Free embryos which are more than 15 seconds old.
     2875         * Free embryos which are more than 5 min old.
    22102876         */
    22112877        uTimestamp = spmTimestamp();
     
    22192885                SPM_ASSERT_PTR_NULL(pProcess->pPrev);
    22202886                if (    pProcess->cReferences == 0
    2221                     &&  uTimestamp - pProcess->uTimestamp >= 15*1000)
     2887                    &&  uTimestamp - pProcess->uTimestamp >= 5*60*1000)
    22222888                {
    22232889                    __LIBC_PSPMPROCESS      pProcessNext = pProcess->pNext;
    2224                     LIBCLOG_MSG("Reaping embryo %p pidParent=%04x pid=%08x pForkHandle=%p uTimestamp=%08x (now=%08x) pNext=%p pPrev=%p\n",
     2890                    LIBCLOG_MSG("Reaping embryo %p pidParent=%#x pid=%#x pForkHandle=%p uTimestamp=%08x (now=%08x) pNext=%p pPrev=%p\n",
    22252891                                (void *)pProcess, pProcess->pidParent, pProcess->pid, pProcess->pvForkHandle, pProcess->uTimestamp, uTimestamp,
    22262892                                (void *)pProcess->pNext, (void *)pProcess->pPrev);
     
    22452911            LIBC_ASSERTM(pProcess->enmState == __LIBC_PROCSTATE_FREE, "enmState=%d pProcess=%p\n",
    22462912                         pProcess->enmState, (void *)pProcess);
    2247             LIBCLOG_MSG("Reaping free process %p (pid=%04x pidParent=%04x)\n",
     2913            LIBCLOG_MSG("Reaping free process %p (pid=%#x pidParent=%#x)\n",
    22482914                        (void *)pProcess, pProcess->pid, pProcess->pidParent);
    22492915
     
    22582924
    22592925        /*
    2260          * Free up inherit data of processes which have been around for more than 15 seconds.
     2926         * Free up inherit data of processes which have been around for more than 5 min.
    22612927         */
    22622928        for (pProcess = gpSPMHdr->apHeads[__LIBC_PROCSTATE_ALIVE]; pProcess; pProcess = pProcess->pNext)
     
    22662932            SPM_ASSERT_PTR_NULL(pProcess->pPrev);
    22672933            if (    pProcess->pInherit
    2268                 &&  uTimestamp - pProcess->uTimestamp >= 15*1000)
     2934                &&  uTimestamp - pProcess->uTimestamp >= 5*60*1000)
    22692935            {
    22702936                void *pv = (void *)__atomic_xchg((unsigned *)(void *)&gpSPMSelf->pInherit, 0);
    2271                 LIBCLOG_MSG("Reaping inherit data (%p) of process %p (pid=%04x pidParent=%04x)\n",
     2937                LIBCLOG_MSG("Reaping inherit data (%p) of process %p (pid=%#x pidParent=%#x)\n",
    22722938                            pv, (void *)pProcess, pProcess->pid, pProcess->pidParent);
    22732939                spmFree(pv);
    22742940            }
     2941        }
     2942
     2943        /*
     2944         * Free up termination structures.
     2945         */
     2946        __LIBC_PSPMCHILDNOTIFY pNotify;
     2947        for (pNotify = gpSPMHdr->pChildNotifyFreeHead; pNotify;)
     2948        {
     2949            LIBCLOG_MSG("Reaping notification record %p (cb=%d pid=%#x iExitCode=%d enmDeathReason=%d)\n",
     2950                        (void *)pNotify, pNotify->cb, pNotify->pid, pNotify->iExitCode, pNotify->enmDeathReason);
     2951            __LIBC_PSPMCHILDNOTIFY pFree = pNotify;
     2952            pNotify = pNotify->pNext;
     2953            pFree->pNext = NULL;
     2954            spmFree(pFree);
    22752955        }
    22762956
     
    22792959         */
    22802960        pv = spmAllocSub(cbSize);
     2961        if (!pv)
     2962        {
     2963            LIBCLOG_MSG("SPM IS *STILL* LOW ON MEMORY!!! cbFree=%d cb=%d (cbSize=%d)\n", gpSPMHdr->cbFree, gpSPMHdr->cb, cbSize);
     2964
     2965            /*
     2966             * Free embryos which are more than 15 seconds old.
     2967             */
     2968            uTimestamp = spmTimestamp();
     2969            pProcess = gpSPMHdr->apHeads[__LIBC_PROCSTATE_EMBRYO];
     2970            if (pProcess)
     2971            {
     2972                do
     2973                {
     2974                    SPM_ASSERT_PTR_NULL(pProcess);
     2975                    SPM_ASSERT_PTR_NULL(pProcess->pNext);
     2976                    SPM_ASSERT_PTR_NULL(pProcess->pPrev);
     2977                    if (    pProcess->cReferences == 0
     2978                        &&  uTimestamp - pProcess->uTimestamp >= 15*1000)
     2979                    {
     2980                        __LIBC_PSPMPROCESS      pProcessNext = pProcess->pNext;
     2981                        LIBCLOG_MSG("Reaping embryo %p pidParent=%#x pid=%#x pForkHandle=%p uTimestamp=%08x (now=%08x) pNext=%p pPrev=%p\n",
     2982                                    (void *)pProcess, pProcess->pidParent, pProcess->pid, pProcess->pvForkHandle, pProcess->uTimestamp, uTimestamp,
     2983                                    (void *)pProcess->pNext, (void *)pProcess->pPrev);
     2984                        spmFreeProcess(pProcess);
     2985                        pProcess = pProcessNext;
     2986                        continue;
     2987                    }
     2988
     2989                    /* next */
     2990                    pProcess = pProcess->pNext;
     2991                } while (pProcess);
     2992            }
     2993
     2994            /*
     2995             * Free up inherit data of processes which have been around for more than 15 seconds.
     2996             */
     2997            for (pProcess = gpSPMHdr->apHeads[__LIBC_PROCSTATE_ALIVE]; pProcess; pProcess = pProcess->pNext)
     2998            {
     2999                SPM_ASSERT_PTR_NULL(pProcess);
     3000                SPM_ASSERT_PTR_NULL(pProcess->pNext);
     3001                SPM_ASSERT_PTR_NULL(pProcess->pPrev);
     3002                if (    pProcess->pInherit
     3003                    &&  uTimestamp - pProcess->uTimestamp >= 15*1000)
     3004                {
     3005                    void *pv = (void *)__atomic_xchg((unsigned *)(void *)&gpSPMSelf->pInherit, 0);
     3006                    LIBCLOG_MSG("Reaping inherit data (%p) of process %p (pid=%#x pidParent=%#x)\n",
     3007                                pv, (void *)pProcess, pProcess->pid, pProcess->pidParent);
     3008                    spmFree(pv);
     3009                }
     3010            }
     3011
     3012            /*
     3013             * Free preallocated signals.
     3014             */
     3015            while (gpSPMHdr->cSigFree > 4 && gpSPMHdr->pSigFreeHead)
     3016            {
     3017                __LIBC_PSPMSIGNAL pSig = gpSPMHdr->pSigFreeHead;
     3018                gpSPMHdr->pSigFreeHead = pSig->pNext;
     3019                gpSPMHdr->cSigFree--;
     3020                pSig->pNext = NULL;
     3021                spmFree(pSig);
     3022            }
     3023        }
    22813024    }
    22823025
     
    26683411        LIBCLOG_REL("SPM Exception! Owner of the mutex!\n");
    26693412    else
    2670         LIBCLOG_REL("SPM Exception! Not owner of the mutex! owner: tid=%ld pid=%ld cNesting=%ld\n", tid, pid, cNesting);
     3413        LIBCLOG_REL("SPM Exception! Not owner of the mutex! owner: tid=%lx (%ld) pid=%lx (%ld) cNesting=%ld\n",
     3414                    tid, tid, pid, pid, cNesting);
    26713415
    26723416    /*
     
    27753519        /* check head backpointer. */
    27763520        if (SPM_VALID_PTR(gpSPMHdr->apHeads[i]) && gpSPMHdr->apHeads[i]->pPrev)
    2777             CHECK_FAILED("Invalid list head in list %i. pPrev != NULL. pPrev=%p pProcess=%p pid=%#06x\n",
     3521            CHECK_FAILED("Invalid list head in list %i. pPrev != NULL. pPrev=%p pProcess=%p pid=%#x\n",
    27783522                         i, (void *)gpSPMHdr->apHeads[i]->pPrev, (void *)gpSPMHdr->apHeads[i], gpSPMHdr->apHeads[i]->pid);
    27793523
     
    27893533                break;
    27903534            CHECK_LOG("pProcess=%08x enmState=%d cReferences=%d pid=%#06x pidParent=%#06x pInherit=%08x cSPMOpens=%d pNext=%08x pPrev=%08x\n",
    2791                             (uintptr_t)pProcess, pProcess->enmState, pProcess->cReferences, pProcess->pid, pProcess->pidParent,
    2792                             (uintptr_t)pProcess->pInherit, pProcess->cSPMOpens, (uintptr_t)pProcess->pNext, (uintptr_t)pProcess->pPrev);
     3535                      (uintptr_t)pProcess, pProcess->enmState, pProcess->cReferences, pProcess->pid, pProcess->pidParent,
     3536                      (uintptr_t)pProcess->pInherit, pProcess->cSPMOpens, (uintptr_t)pProcess->pNext, (uintptr_t)pProcess->pPrev);
    27933537
    27943538            sprintf(sz, "i=%d pid=%#06x\n", i, pProcess->pid);
  • trunk/src/emx/src/lib/sys/signals.c

    • Property cvs2svn:cvs-rev changed from 1.9 to 1.10
    r1628 r1629  
    556556static int              signalJobStop(int iSignalNo);
    557557static int              signalJobResume(void);
     558static int              signalSendPGrpCallback(int iSignalNo, const __LIBC_SPMPROCESS *pProcess, void *pvUser);
    558559static int              signalActionWorker(__LIBC_PTHREAD pCur, void *pvParam);
    559560static unsigned         signalTimestamp(void);
     
    911912 * @param   fFlags              Flags of the #defines __LIBC_BSRF_* describing how to
    912913 *                              deliver the signal.
    913  *
    914  * @remark  This Backend Signal API does NOT require the caller to own the signal semaphore.
    915914 */
    916915int __libc_Back_signalRaise(int iSignalNo, siginfo_t *pSigInfo, void *pvXcptOrQueued, unsigned fFlags)
     
    13191318                        /* Shit! We failed to queue it on a thread. Try put it back in the 1st level queue. */
    13201319                        LIBCLOG_MSG("failed to schedule signal %d for any thread!\n", iSignalNo);
    1321                         __libc_spmSigQueue(&SigInfo, _sys_pid, !!(SigInfo.si_flags & __LIBC_SI_QUEUED));
     1320                        __libc_spmSigQueue(SigInfo.si_signo, &SigInfo, _sys_pid, !!(SigInfo.si_flags & __LIBC_SI_QUEUED));
    13221321                        break;
    13231322                    }
     
    21342133 * @param   pSigInfo    Signal info (optional).
    21352134 */
    2136 int __libc_back_signalSendPidOther(pid_t pid, int iSignalNo, siginfo_t *pSigInfo)
     2135int __libc_back_signalSendPidOther(pid_t pid, int iSignalNo, const siginfo_t *pSigInfo)
    21372136{
    21382137    LIBCLOG_ENTER("pid=%d iSignalNo=%d pSigInfo=%p\n", pid, iSignalNo, (void *)pSigInfo);
     
    21422141
    21432142    /*
    2144      * Send the signal.
    2145      */
    2146     if (pSigInfo)
    2147     {
    2148         switch (iSignalNo)
    2149         {
    2150             /*
    2151              * SIGKILL means kill process.
    2152              */
    2153             case SIGKILL:
    2154                 FS_SAVE_LOAD();
    2155                 rcOS2 = DosKillProcess(DKP_PROCESS, pid);
    2156                 FS_RESTORE();
    2157                 switch (rcOS2)
    2158                 {
    2159                     case NO_ERROR:
    2160                         LIBCLOG_RETURN_INT(0);
    2161 
    2162                     case ERROR_INVALID_PROCID:
    2163                         rc = -ESRCH;
    2164                         break;
    2165                     default:
    2166                         rc = -EPERM;
    2167                         break;
    2168                 }
    2169                 LIBCLOG_RETURN_MSG(rc, "ret %d (DosKillProcess rcOS2=%d)\n", rc, rcOS2);
    2170 
    2171             /*
    2172              * We can send these the normal way to decentants.
    2173              */
    2174             case SIGINT:
    2175             case SIGBREAK:
    2176                 FS_SAVE_LOAD();
    2177                 rcOS2 = DosSendSignalException(pid, iSignalNo == SIGINT ? XCPT_SIGNAL_INTR : XCPT_SIGNAL_BREAK);
    2178                 FS_RESTORE();
    2179                 switch (rcOS2)
    2180                 {
    2181                     case NO_ERROR:
    2182                         LIBCLOG_RETURN_INT(0);
    2183 
    2184                     case ERROR_INVALID_PROCID:
    2185                         LIBCLOG_RETURN_INT(-ESRCH);
    2186                 }
    2187                 /* try flag it */
    2188                 break;
    2189 
    2190             default:
    2191                 break;
    2192         }
    2193     }
    2194 
    2195     /*
    2196      * Try flag the process.
    2197      *
    2198      * If the target is a LIBC process we'll queue a signal on it and poke it.
    2199      * If not we'll convert the signal to EMX and flag it in the EMX compatible way.
     2143     * Attempt queue it assuming it's a LIBC process first.
     2144     * If not a LIBC process (rc is -ESRCH) we'll use alternative
     2145     * methods. First resorting to OS/2 signal exceptions and the to EMX signals.
    22002146     */
    22012147    siginfo_t SigInfo = {0};
     
    22132159        SigInfo.si_flags   |= __LIBC_SI_QUEUED;
    22142160
    2215     rc = __libc_spmSigQueue(&SigInfo, pid, SigInfo.si_flags & __LIBC_SI_QUEUED);
     2161    rc = __libc_spmSigQueue(iSignalNo, &SigInfo, pid, SigInfo.si_flags & __LIBC_SI_QUEUED);
    22162162    if (!rc)
    22172163    {
     2164        if (!iSignalNo)
     2165            LIBCLOG_RETURN_MSG(0, "0 (LIBC permission check ok)\n");
     2166
    22182167        /* poke it... */
    22192168        FS_SAVE_LOAD();
     
    22312180    {
    22322181        /*
     2182         * Check that the process exists first.
     2183         */
     2184        FS_SAVE_LOAD();
     2185        rc = DosVerifyPidTid(pid, 1);
     2186        FS_RESTORE();
     2187        if (rc)
     2188            LIBCLOG_RETURN_MSG(-ESRCH, "%d (-ESRCH) DosVerifyPidTid(%d, 1) -> %d\n", -ESRCH, pid, rc);
     2189        if (!iSignalNo)
     2190            LIBCLOG_RETURN_MSG(0, "0 (OS/2 permission check ok)\n");
     2191
     2192        /*
     2193         * Send the signal.
     2194         */
     2195        switch (iSignalNo)
     2196        {
     2197            /*
     2198             * SIGKILL means kill process.
     2199             */
     2200            case SIGKILL:
     2201                FS_SAVE_LOAD();
     2202                rcOS2 = DosKillProcess(DKP_PROCESS, pid);
     2203                FS_RESTORE();
     2204                switch (rcOS2)
     2205                {
     2206                    case NO_ERROR:                  rc = 0; break;
     2207                    case ERROR_INVALID_PROCID:      rc = -ESRCH; break;
     2208                    default:                        rc = -EPERM; break;
     2209                }
     2210                LIBCLOG_RETURN_MSG(rc, "ret %d (DosKillProcess rcOS2=%d)\n", rc, rcOS2);
     2211
     2212            /*
     2213             * We can send these the normal way to decentants.
     2214             */
     2215            case SIGINT:
     2216            case SIGBREAK:
     2217                FS_SAVE_LOAD();
     2218                rcOS2 = DosSendSignalException(pid, iSignalNo == SIGINT ? XCPT_SIGNAL_INTR : XCPT_SIGNAL_BREAK);
     2219                FS_RESTORE();
     2220                switch (rcOS2)
     2221                {
     2222                    case NO_ERROR:
     2223                        LIBCLOG_RETURN_INT(0);
     2224                    case ERROR_INVALID_PROCID:
     2225                        LIBCLOG_RETURN_INT(-ESRCH);
     2226                }
     2227                /* try flag it */
     2228                break;
     2229
     2230            default:
     2231                break;
     2232        }
     2233
     2234        /*
    22332235         * EMX style signal.
    2234          * Doesn't work for all types of signals.
     2236         *
     2237         * Doesn't work for all types of signals and only if process is EMX.
     2238         * The latter we cannot easily check...
    22352239         */
    22362240        unsigned uSignalEMX = 0;
     
    22782282
    22792283    /*
    2280      * Check for DosFlagProcess errors.
     2284     * Check for DosFlagProcess error.
    22812285     */
    22822286    if (!rc)
     
    22852289    LIBCLOG_RETURN_INT(rc);
    22862290}
     2291
     2292/**
     2293 * Sends a signal to a process group.
     2294 *
     2295 * Special case for iSignalNo equal to 0, where no signal is sent but permissions to
     2296 * do so is checked.
     2297 *
     2298 * @returns 0 on if signal sent.
     2299 * @returns -errno on failure.
     2300 *
     2301 * @param   pgrp        Process group (positive).
     2302 *                      0 means the process group of this process.
     2303 *                      1 means all process in the system. (not implemented!)
     2304 * @param   iSignalNo   Signal to send to all the processes in the group.
     2305 *                      If 0 no signal is sent, but error handling is done as if.
     2306 */
     2307int         __libc_Back_signalSendPGrp(pid_t pgrp, int iSignalNo)
     2308{
     2309    LIBCLOG_ENTER("pgrp=%#x (%d) iSignalNo=%d\n", pgrp, pgrp, iSignalNo);
     2310    int     rc;
     2311
     2312    /*
     2313     * Validate input.
     2314     */
     2315    if (!__SIGSET_SIG_VALID(iSignalNo) && iSignalNo != 0)
     2316    {
     2317        LIBC_ASSERTM_FAILED("Invalid signal no. %d\n", iSignalNo);
     2318        LIBCLOG_RETURN_INT(-EINVAL);
     2319    }
     2320    if (pgrp < 0 || pgrp == 1)
     2321    {
     2322        LIBC_ASSERTM_FAILED("Invalid pgrp %d\n", pgrp);
     2323        LIBCLOG_RETURN_INT(-EINVAL);
     2324    }
     2325
     2326    /*
     2327     * Create signal packet.
     2328     */
     2329    siginfo_t SigInfo = {0};
     2330    SigInfo.si_signo        = iSignalNo;
     2331    if (SigInfo.si_pid)
     2332        SigInfo.si_pid      = _sys_pid;
     2333    __LIBC_PTHREAD pThrd    = __libc_threadCurrentNoAuto();
     2334    if (pThrd)
     2335        SigInfo.si_tid      = pThrd->tid;
     2336    if (SigInfo.si_timestamp)
     2337        SigInfo.si_timestamp= signalTimestamp();
     2338    if (gafSignalProperties[iSignalNo] & SPP_QUEUED)
     2339        SigInfo.si_flags   |= __LIBC_SI_QUEUED;
     2340
     2341    /*
     2342     * Take the signal semaphore.
     2343     */
     2344    rc = __libc_back_signalSemRequest();
     2345    if (rc)
     2346        LIBCLOG_RETURN_INT(rc);
     2347
     2348    /*
     2349     * Call SPM to do the enumeration and queueing.
     2350     */
     2351    rc = __libc_spmSigQueuePGrp(iSignalNo, &SigInfo, pgrp, SigInfo.si_flags & __LIBC_SI_QUEUED, signalSendPGrpCallback, NULL);
     2352
     2353    __libc_back_signalSemRelease();
     2354    LIBCLOG_RETURN_INT(rc);
     2355}
     2356
     2357
     2358/**
     2359 * Callback for poking a process which was signaled as part of a group signaling.
     2360 * @returns 0 on success.
     2361 */
     2362static int signalSendPGrpCallback(int iSignalNo, const __LIBC_SPMPROCESS *pProcess, void *pvUser)
     2363{
     2364    LIBCLOG_ENTER("iSignalNo=%d pProcess=%p {pid=%#x} pvUser=%p\n", iSignalNo, (void *)pProcess, pProcess->pid, pvUser);
     2365    if (!iSignalNo)
     2366        LIBCLOG_RETURN_MSG(0, "0 (LIBC permission check ok)\n");
     2367
     2368    /* poke it... */
     2369    FS_VAR();
     2370    FS_SAVE_LOAD();
     2371    int rc = DosFlagProcess(pProcess->pid, FLGP_PID, PFLG_A, 0);
     2372    if (rc == ERROR_SIGNAL_REFUSED)
     2373    {
     2374        /* Try again... no sure what would cause this condition... */
     2375        DosSleep(0);
     2376        DosSleep(1);
     2377        rc = DosFlagProcess(pProcess->pid, FLGP_PID, PFLG_A, 0);
     2378    }
     2379    FS_RESTORE();
     2380    if (!rc)
     2381        LIBCLOG_RETURN_INT(0);
     2382    rc = -__libc_native2errno(rc);
     2383    LIBCLOG_RETURN_INT(rc);
     2384}
     2385
    22872386
    22882387
  • trunk/src/emx/src/lib/sys/signals.h

    • Property cvs2svn:cvs-rev changed from 1.4 to 1.5
    r1628 r1629  
    5353int         __libc_back_signalAccept(__LIBC_PTHREAD pThrd, int iSignalNo, sigset_t *pSigSet, siginfo_t *pSigInfo);
    5454int         __libc_back_signalWait(__LIBC_PTHREAD pThrd, volatile int *pfDone, const struct timespec *pTimeout);
    55 int         __libc_back_signalSendPidOther(pid_t pid, int iSignalNo, siginfo_t *pSigInfo);
     55int         __libc_back_signalSendPidOther(pid_t pid, int iSignalNo, const siginfo_t *pSigInfo);
    5656int         __libc_back_signalAction(int iSignalNo, const struct sigaction *pSigAct, struct sigaction *pSigActOld);
    5757int         __libc_back_signalRaisePoked(void *pvXcptParams, int tidPoker);
Note: See TracChangeset for help on using the changeset viewer.