fork()
  • ede
  • Caterpillar
    Caterpillar
    ede
    Posts: 35 from 2011/4/19
    From: Poland
    Hi,

    I found an example of source code that replaces the fork () function. How to compile it on MorphOS ?

    Code:
    /*
    * fork.c -- An example of using ixemul.library pseudo-forking function
    *
    * Copyright (c) 2011 Tygre (yann-gael@gueheneuc.net)
    *
    * This program is free software: you can redistribute it and/or modify
    * it under the terms of the GNU General Public License as published by
    * the Free Software Foundation, either version 3 of the License, or
    * (at your option) any later version.
    *
    * This program is distributed in the hope that it will be useful,
    * but WITHOUT ANY WARRANTY; without even the implied warranty of
    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    * GNU General Public License for more details.
    *
    * You should have received a copy of the GNU General Public License
    * along with this program. If not, see <http://www.gnu.org/licenses/>.
    */
    #include <errno.h>
    #include <stdio.h>
    #include <ix.h>

    #define MAX_COUNT 5
    #define BUF_SIZE 100


    /*
    * The function that will be called by two separate processes.
    * It just prints out MAX_COUNT times a counter while sleeping
    * in between each print to show the "forking".
    */

    extern char **_ctype_, **environ;
    extern int sys_nerr;
    extern int SysBase, DOSBase;


    static void forked_print(char *id)
    {
    pid_t pid = getpid();
    int i;
    char buf[BUF_SIZE];

    srand(time(NULL));

    sprintf(buf, "%s pid is %dn", id, pid);
    write(1, buf, strlen(buf));

    for (i = 1; i <= MAX_COUNT; i++) {
    sprintf(buf, "%s, with pid %d, value = %dn", id, pid, i);
    write(1, buf, strlen(buf));
    sleep(rand() % 4);
    }
    sprintf(buf, "%s, with pid %d, just quitted!n", id, pid);
    write(1, buf, strlen(buf));
    }



    /*
    * This function does the "magic" of "forking" the main process.
    * It is heavily inspired by the function "branch" available in
    * the 0.9.9 release of "binkd" in the file "branch.c".
    * Below is the copying permission statement from "branch.c":
    *
    * branch.c -- Create co-processes
    *
    * branch.c is a part of binkd project
    *
    * Copyright (C) 1996-1998 Dima Maloff, 5047/13
    *
    * This program is free software; you can redistribute it and/or modify
    * it under the terms of the GNU General Public License as published by
    * the Free Software Foundation; either version 2 of the License, or
    * (at your option) any later version. See COPYING.
    */
    static int branch(register void (*F) (void *), register void *arg, register size_t size)
    {
    char buf[BUF_SIZE];
    register int rc;
    static char *tmp;

    /*
    * We print out some information regarding the "arg" and its "size".
    */
    sprintf(buf, "Before ix_vfork, arg: %d, size: %dn", arg, size);
    write(1, buf, strlen(buf));


    if(!(rc = ix_vfork()))
    {

    vfork_setup_child();

    /*
    * We make our own copy of arg for the child as the parent
    * may destroy it before the child finish to use it.
    */
    if(size > 0)
    {
    if((tmp = malloc(size)) == NULL)
    {
    perror("Malloc failed");
    return -1;
    }
    else
    {
    memcpy(tmp, arg, size);
    }
    }
    else
    {
    tmp = 0;
    }

    /*
    * We print out some information regarding the "arg" and its copy, "tmp".
    * It is important to note that the pointer value for "arg" did not change
    * after the "forking" because it is not a true "forking" but rather the
    * creation of a thread.
    * See http://binkd.sourcearchive.com/documentation/0.9.9plus-p20060809-1/branch_8c-source.html
    */
    sprintf(buf, "Before ix_vfork, arg: %d, tmp: %dn", arg, tmp);
    write(1, buf, strlen(buf));

    ix_vfork_resume();
    F(tmp);
    free(tmp);
    _exit(0);
    }
    else if (rc < 0)
    {
    sprintf(buf, "ix_vfork: %sn", strerror(errno));
    write(1, buf, strlen(buf));
    }

    return rc;
    }



    int main(void)
    {
    char id[2];

    /*
    * We "fork" the function "forked_print", using "C" to denote the child.
    */
    sprintf(id, "C");
    if(branch((void *) forked_print, (void *) id, sizeof(id)) < 0)
    {
    perror("Cannot branch!");
    }
    else
    {
    /*
    * We call the function "forked_print" in the parent process, using "P".
    */
    sprintf(id, "P");
    sleep(3);
    forked_print(id);
    }
    exit(0);
    }


    [ Edited by ede 22.02.2015 - 21:45 ]
  • »22.02.15 - 21:44
    Profile