![]() |
![]() |
#1 |
Returning fan!
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,442
|
Amiga, vfork(), and pipe()
Dear all!
In my endless ![]() The function fork() does not exist in AmigaOS (at least 3.1, m68k), so it must be replaced and vfork() seems like a good idea but for the fact that it spawns a process that run in parallel to the parent process only if execve() is called. This behaviour is fine except that, before calling execve(), THTTPd sets up a listener to listen to the output of the CGI script... which is spawned using vfork(), which prevent the call to execve()! ![]() Any suggestions to solve this "deadlock" problem? Cheers! Tygre |
![]() |
![]() |
#2 |
Returning fan!
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,442
|
PS. Digging in the Internet, I found out that ixemul.library provide replacement functions to vfork():
Even better, I found an example of using these functions to "fork" a function call in binkd, a Binkley deamon - TCP/IP Fidonet mailer. Its executable is available in Aminet (v2.0). Its source code is available in launchpad.net (v0.9.9) ![]() Let's see if I can draw inspiration from binkd! ![]() |
![]() |
![]() |
#3 |
Registered User
Join Date: Nov 2006
Location: Stockholm, Sweden
Posts: 237
|
Quoting a bit from ixemul manual:
"In some cases, such as a Unix shell (pdksh for example), you really want to be able to port a program that uses a fork() that cannot be replaced with vfork(). There is a way to do this, although it is a lot of work. First of all, the program has to be compiled with -resident. Now you replace the fork() by a ix_vfork() call, and in the child code you call vfork_setup_child() (new for 44.0! Replaces the ix_resident()/ix_get_vars2() pair) to copy the original data hunk to a new location. Next you have to copy all the parent's data structures to the child. In other words, you have to copy the complete state of the parent process to the child process. This can be a lot of work. Finally, you call vfork_resume() which unblocks the parent so that you now have two processes running separately from each other. It is important to realize that you should never exit() from the parent before all vfork()'ed children have died. Since exiting from the parent causes the parents code and data segments to be deallocated, the child would find itself without code space to run on, and would probably cause a severe machine crash! So always call at least `wait(0)' before returning from the parent." Yeah, you might be able to do it via ix_vfork(). it's not 100% clear whether stdin/stout redirection will work as intended though. You might have to bite the bullet and use the native AmigaOS function instead (CreateNewProc). |
![]() |
![]() |
#4 |
Returning fan!
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,442
|
@Kalms!
Yes, I read that ![]() Thanks! |
![]() |
![]() |
#5 |
Returning fan!
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,442
|
Dear all!
Thanks to binkd and other sources on the Internet, I think that I was able to correctly use the ixemul.library to "fork" processes ![]() 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". */ static void forked_print(char *id) { pid_t pid = getpid(); int i; char buf[BUF_SIZE]; srand(time(NULL)); sprintf(buf, "%s pid is %d\n", id, pid); write(1, buf, strlen(buf)); for (i = 1; i <= MAX_COUNT; i++) { sprintf(buf, "%s, with pid %d, value = %d\n", 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: %d\n", 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: %d\n", arg, tmp); write(1, buf, strlen(buf)); ix_vfork_resume(); F(tmp); free(tmp); _exit(0); } else if (rc < 0) { sprintf(buf, "ix_vfork: %s\n", 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); } Code:
/usr/local/amiga/bin/m68k-amigaos-gcc.exe fork.c -o fork Code:
Before ix_vfork, arg: ...10, size: 2 Before ix_vfork, arg: ...10, tmp: ...28 C pid is ...60 C, with pid ...60, value = 1 C, with pid ...60, value = 2 C pid is ...36 P, with pid ...36, value = 1 C, with pid ...60, value = 3 P, with pid ...36, value = 2 C, with pid ...60, value = 4 P, with pid ...36, value = 3 P, with pid ...36, value = 4 C, with pid ...60, value = 5 P, with pid ...36, value = 5 P, with pid ...36, just quitted! C, with pid ...60, just quitted! ![]() Cheers! Tygre Last edited by tygre; 03 December 2011 at 02:12. Reason: Slightly improved the example code |
![]() |
![]() |
#6 |
Amiga Member
Join Date: Aug 2003
Location: New Zealand
Age: 57
Posts: 695
|
I must remember this if I ever go back to compiling some of my mud codebases
My solution back in the day was simply to remove the sprawling task and I don't think I even did that cleanly LOL I'm a cut and paster not a coder... but I can compile, insert missing headers and insert the odd missing function... |
![]() |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
Project: Blizzard 1230 IV - Heat Pipe Cooling System | Yoto | support.Hardware | 45 | 17 December 2012 05:45 |
Pipe Dream (original) | MethodGit | request.Old Rare Games | 3 | 16 December 2010 22:17 |
Pipe Mania - AGA-fixed/1-filed by Galahad | MethodGit | request.Old Rare Games | 10 | 28 May 2009 01:34 |
|
|