Esempio n. 1
0
int
__getosreldate(void)
{
    static int osreldate;

    char *temp;

    if (osreldate == 0)
    {
	if ((temp = getenv("OSVERSION"))) {
		osreldate = atoi(temp);
		return (osreldate);
	}

	osreldate = __kernel_getosreldate ();
    }		
    return (osreldate);
}
Esempio n. 2
0
int __clone (int (*fn) (void *), void *child_stack, int flags, void *arg)
{
    int rfork_flags = RFPROC;

    if (fn == NULL || child_stack == NULL)
    {
        __set_errno (EINVAL);
        return -1;
    }

    /* This implementation of clone() does not support all Linux flags.  */
    if (flags & ~(CSIGNAL | CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND
                  | CLONE_VFORK | CLONE_SYSVSEM))
    {
        __set_errno (EINVAL);
        return -1;
    }

    if ((flags & CSIGNAL) != SIGCHLD)
    {
        if (__kernel_getosreldate() >= 802510)
            /* we slightly cheat here, */
            /* the 9.x snapshot prior to r223966 does not support it too */
        {
            if ((flags & CSIGNAL) & ~RFTSIGMASK)
            {
                __set_errno (EINVAL);
                return -1;
            }
            rfork_flags |= (RFTSIGZMB | RFTSIGFLAGS(flags & CSIGNAL));
        }
        else
        {
            if ((flags & CSIGNAL) & ~RFTHPNMASK)
            {
                __set_errno (EINVAL);
                return -1;
            }
            if ((flags & CSIGNAL) == 0)
                rfork_flags |= (RFLINUXTHPN | ((SIGCHLD) <<  RFTHPNSHIFT));
            else
                rfork_flags |= (RFLINUXTHPN | ((flags & CSIGNAL) <<  RFTHPNSHIFT));
        }
    }
    if (flags & CLONE_VM)
        rfork_flags |= RFMEM;

    if (flags & CLONE_FS)
        /* Sharing the filesystem related info (umask, cwd, root dir)
           is not supported by rfork.  Ignore this; let's hope programs
           will set their umask and cwd before spawning threads.  */
        ;

    if (flags & CLONE_SYSVSEM)
        /* Ignore this; it has been introduced into linuxthreads in post 2.4 glibc */
        ;

    if (!(flags & CLONE_FILES))
        rfork_flags |= RFFDG;

    if (flags & CLONE_SIGHAND)
    {
        rfork_flags |= RFSIGSHARE;
        /* Also set the undocumented flag RFTHREAD.  It has the effect that when
        the thread leader exits, all threads belonging to it are killed.  */
        rfork_flags |= RFTHREAD;
    }

    if (flags & CLONE_VFORK)
        rfork_flags |= RFPPWAIT;

    return __start_thread (rfork_flags, child_stack, fn, arg);
}