Who's Online |
101 user(s) are online ( 50 user(s) are browsing Forums)
Members: 1
Guests: 100
Georg,
more...
|
|
Headlines |
-
amidisas.tar.bz2 - development/utility
Apr 16, 2024
-
wildmidi.lha - audio/play
Apr 15, 2024
-
liba52.lha - development/library/audio
Apr 14, 2024
-
libcurl.lha - development/library/misc
Apr 14, 2024
-
libopenssl.lha - development/library/misc
Apr 14, 2024
-
bermudasyndrome.lha - game/action
Apr 14, 2024
-
amigagpt.lha - network/chat
Apr 14, 2024
-
curl.lha - network/misc
Apr 14, 2024
-
dgen_sdl.lha - emulation/gamesystem
Apr 12, 2024
-
amiarcadia.lha - emulation/gamesystem
Apr 11, 2024
|
|
|
|
Re: OS4.1 bugs
|
Posted on: 2009/3/27 16:26
#101
|
Just popping in
|
@Chris
Besides the fact that every one of those functions actually has a return code, there is no checking being done. Also, the 'posn' variable is supposed to be signed.
However, semantics aside, you did actually find an issue with OFFSET_CURRENT with JXFS filesystem, the fix will be in the update due out shortly.
Thanks for finding that.
|
|
|
|
Re: Subscribing to file system notifications
|
Posted on: 2009/3/27 12:27
#102
|
Just popping in
|
@abalaban Yes, go ahead....
|
|
|
|
Re: How do you set a "stack cookie?"
|
Posted on: 2009/3/27 3:26
#103
|
Just popping in
|
@rwo
Yes, DOS uses it in RunCommand(). Workbench uses it too, and also the shell handler.
See; IDOS->FindSegmentStackSize() function.
|
|
|
|
Re: How do you set a "stack cookie?"
|
Posted on: 2009/3/26 15:49
#104
|
Just popping in
|
@Rigo
Just use the USED define in amiga-compiler.h which is automatically included.
static USED const char *stack = "$STACK:65535";
|
|
|
|
Re: Check existence of assign
|
Posted on: 2009/3/22 15:51
#105
|
Just popping in
|
@BillE
APTR oldwin = IDOS->SetProcWindow((APTR)-1); BPTR lock = IDOS->Lock(assign_name,SHARED_LOCK); IDOS->UnLock(lock); /* 0 safe */ IDOS->SetProcWindow(oldwin);
if( lock ) { IDOS->Printf("%s exists\n",assign_name); } else { IDOS->Printf("%s does not exist\n",assign_name); }
|
|
|
|
Re: Subscribing to file system notifications
|
Posted on: 2009/3/21 16:06
#106
|
Just popping in
|
@orgin Here's the source code for a test program I used for the DOS notify handler. It's a bit messy, but i'm too-lazy to tidy it up. Compile it as is (with -nostdlib) and you will see all three methods at work. Start it from a shell with one argument that is the path to the filesystem object to be monitored.
=====================================================
#define __NOLIBBASE__
#define __NOGLOBALIFACE__
#include <proto/exec.h>
#include <proto/dos.h>
#include <dos/startup.h>
/****************************************************************************/
struct CustomHook
{
struct Hook H; /* must be first */
struct ExecIFace *IExec;
struct DOSIFace *IDOS;
BPTR Output;
ULONG Line;
};
TEXT *actions[] =
{
"NHM_ACTION_INITIAL",
"NHM_ACTION_ADD",
"NHM_ACTION_CHANGE",
"NHM_ACTION_DELETE",
NULL
};
/****************************************************************************/
STATIC LONG HookFunc( struct CustomHook *hook, APTR resv UNUSED, struct NotifyHookMsg *msg )
{
LONG indx = msg->nhm_Action;
indx ++; /* starts at -1 */
indx &= 3;
hook->IDOS->FPrintf(hook->Output,"%04lu HOOK Ping; '%s' [%s]\n",
hook->Line++, msg->nhm_Name, actions[indx]);
return(0);
}
/****************************************************************************/
STATIC LONG mmain( struct ExecIFace *IExec, struct DOSIFace * IDOS )
{
TEXT namebuf[256];
struct NotifyRequest *nr_hook = NULL;
struct NotifyRequest *nr_sig = NULL;
struct NotifyRequest *nr_msg = NULL;
struct MsgPort *mport = NULL;
struct CustomHook HK;
LONG numnotify =0;
LONG ok = 0;
STRPTR args;
IDOS->ReadItem(namebuf,sizeof(namebuf),NULL);
args = namebuf;
if( *args <= 32 )
{
args = "RAM:";
}
if( '?' == *args )
{
IDOS->PutStr("USAGE: Notify <file/directory> \nIf not specified, defaults to RAM:\n\n");
return(RETURN_FAIL);
}
/*************** HOOK **************/
HK.H.h_Entry = (APTR) &HookFunc;
HK.IExec = IExec;
HK.IDOS = IDOS;
HK.Output = IDOS->Output();
numnotify ++;
nr_hook = IDOS->AllocDosObjectTags( DOS_NOTIFYREQUEST,
ADO_NotifyName, args,
ADO_NotifyMethod, NRF_CALL_HOOK,
ADO_DOSMethodOnly,TRUE,
ADO_NotifyInitial, TRUE,
ADO_NotifyHook, &HK,
TAG_DONE );
if( nr_hook )
{
if( IDOS->StartNotify( nr_hook ) )
{
// IDOS->Printf("DOS HOOK Notification started for '%s' as '%s'\n", nr_hook->nr_Name, nr_hook->nr_FullName);
ok ++;
}
else
{
IDOS->Printf("DOS HOOK Notification FAILED because; %m\n", 0);
}
}
else
{
IDOS->Printf("ADO(DOS_NOTIFYREQUEST,HOOK) FAILED because; %m \n",0);
}
/*************** SIGNAL **************/
numnotify ++;
nr_sig = IDOS->AllocDosObjectTags( DOS_NOTIFYREQUEST,
ADO_NotifyName, args,
ADO_NotifyMethod, NRF_SEND_SIGNAL,
ADO_DOSMethodOnly,TRUE,
ADO_NotifyTask, IExec->FindTask(NULL),
ADO_NotifySignalNumber, SIGBREAKB_CTRL_F,
ADO_NotifyInitial, TRUE,
TAG_DONE );
if( nr_sig )
{
if( IDOS->StartNotify( nr_sig ) )
{
// IDOS->Printf("DOS SIGNAL Notification started for '%s' as '%s'\n", nr_sig->nr_Name, nr_sig->nr_FullName);
ok ++;
}
else
{
IDOS->Printf("DOS SIGNAL Notification FAILED because; %m\n", 0);
}
}
else
{
IDOS->Printf("ADO(DOS_NOTIFYREQUEST,SIGNAL) FAILED because; %m \n",0);
}
/*************** MESSAGE **************/
numnotify ++;
if(( mport = IExec->CreateMsgPort() ))
{
nr_msg = IDOS->AllocDosObjectTags( DOS_NOTIFYREQUEST,
ADO_NotifyName, args,
ADO_NotifyMethod, NRF_SEND_MESSAGE,
ADO_DOSMethodOnly,TRUE,
ADO_NotifyPort, mport,
ADO_NotifyInitial, TRUE,
TAG_DONE );
if( nr_msg )
{
if( IDOS->StartNotify( nr_msg ) )
{
// IDOS->Printf("DOS MESSAGE Notification started for '%s' as '%s'\n", nr_msg->nr_Name, nr_msg->nr_FullName);
ok ++;
}
else
{
IDOS->Printf("DOS MESSAGE Notification FAILED because; %m\n", 0);
}
}
else
{
IDOS->Printf("ADO(DOS_NOTIFYREQUEST,MESSAGE) FAILED because; %m \n",0);
}
}
//leave:
if( numnotify == ok )
{
ULONG signal, portmask=0;
struct Message *msg = NULL;
HK.Line = 1;
IDOS->PutStr("Ready: ^C to exit.......\n");
if( mport )
{
portmask = 1UL << mport->mp_SigBit;
}
do
{
// IDOS->PutStr("\n");
signal = IExec->Wait( SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_F | portmask );
if( signal & SIGBREAKF_CTRL_F )
{
IDOS->Printf("%04lu SIGNAL Ping; '%s'\n", HK.Line++, nr_sig->nr_FullName);
}
if( signal & portmask )
{
IDOS->Printf("%04lu MESSAGE Ping; '%s'\n", HK.Line++, nr_sig->nr_FullName);
while(( msg = IExec->GetMsg(mport) ))
{
IDOS->PutStr(" -- MESSAGE_REPLIED\n\n");
IExec->ReplyMsg(msg);
}
}
}
while( ! (signal & SIGBREAKF_CTRL_C));
IDOS->PutStr("\nProgram Exit.....\n\n");
}
IDOS->EndNotify( nr_hook );
IDOS->FreeDosObject( DOS_NOTIFYREQUEST, nr_hook );
IDOS->EndNotify( nr_sig );
IDOS->FreeDosObject( DOS_NOTIFYREQUEST, nr_sig );
IDOS->EndNotify( nr_msg );
IDOS->FreeDosObject( DOS_NOTIFYREQUEST, nr_msg );
if( mport )
{
IExec->DeleteMsgPort(mport);
}
return(RETURN_OK);
}
/****************************************************************************/
LONG _start(STRPTR args UNUSED, LONG arglen UNUSED, struct ExecBase *SysBase)
{
struct ExecIFace *IExec = (struct ExecIFace *)SysBase->MainInterface;
struct Library *DOSBase = (struct Library *)IExec->OpenLibrary(DOSNAME, 50);
long rc = RETURN_ERROR;
if (DOSBase)
{
struct DOSIFace *IDOS = (struct DOSIFace *)IExec->GetInterface(DOSBase, "main", 1, NULL);
if (IDOS)
{
rc = mmain(IExec, IDOS);
IExec->DropInterface((struct Interface *)IDOS);
}
IExec->CloseLibrary(DOSBase);
}
return( rc );
}
/****************************************************************************/
TEXT USED vers[] = "\0$VER: It's just a test program, Dammit !!, 52.1 (28.12.2007)\n\r";
/****************************************************************************/
/* EOF */
=====================================================
Edit: Added code tags
Edited by orgin on 2009/3/21 17:35:34 Edited by colinw on 2009/3/22 12:35:29
|
|
|
|
Re: Lock() problem
|
Posted on: 2009/3/16 1:33
#107
|
Just popping in
|
@orgin
Oops !! - Fixed now.
Hmmm, why it took all this time for someone to spot that one. (":/
|
|
|
|
Re: Lock() problem
|
Posted on: 2009/3/15 15:48
#108
|
Just popping in
|
@orgin
Just spotted something.....
The FreeDosObject() of the data block from ExamineDir() is not appropriate in your PathTypeFallback() function.
The data blocks are allocated from a memory pool and stored in the internal list and the whole lot is freed when you call ReleaseDirContext().
However, as you are not looping here, you'd probably never know anything was up.
Because ExamineDir() uses a memory pool and can reuse the nodes on subsequent calls, if you were looping, you'd likely be visited by the reaper for putting it back into the pool but leaving it still in the list without calling IExec->Remove() first. However, seeing you only call ExamineDir() once, you got away with it.
Only ExamineObject() requires you free the data blocks individually when you're done with it.
I've just updated the autodocs to make this point much clearer.
|
|
|
|
Re: Lock() problem
|
Posted on: 2009/3/15 1:29
#109
|
Just popping in
|
@orgin
The issue is that an exclusive lock implies that it is exclusive, and that means no-one else is allowed to futz-around with it.
The best you can do is get a listing of it with a directory scan of the parent directory if you do not have access to the original lock itself.
The filesystem is serious about exclusivity, and if it's not your lock, you're out of luck trying to force access from another client.
The fact that you have limited access to these is by design and not actually a fault.
BTW: You really should first attempt a normal ExamineObject() with the string name before falling through to this fallback method of scanning this entire directory, only if you hit a ERROR_OBJECT_IN_USE error, it will be a hell of a lot faster.
|
|
|
|
Re: Lock() problem
|
Posted on: 2009/3/14 14:38
#110
|
Just popping in
|
@colinw
PS: The EX_FileHandleInput also works the same way as locks when using Examineobject().
|
|
|
|
Re: Lock() problem
|
Posted on: 2009/3/14 14:26
#111
|
Just popping in
|
@orgin // @ToDo: Should probably parse EX_MatchString before using it, even without wildcards
I'll say, it will blow up in your face later if you don't.
|
|
|
|
Re: Lock() problem
|
Posted on: 2009/3/14 14:22
#112
|
Just popping in
|
@orgin
You cannot second Lock() and exclusive lock.
If you read the docs for ExamineObject() you will see that passing a string name implies a Lock(). That's why it fails.
If you already have the exclusive lock, just call ExamineObject() with EX_FileLockInput, that will work on exclusive locks as it is passed to the filesystem directly.
If you want to know the parent directory of the exclusive lock, then call ParentDir() of the exclusive lock, and don't forget to unlock what ParentDir() returns.
|
|
|
|
Re: LockDosList() troubles
|
Posted on: 2009/3/14 14:09
#113
|
Just popping in
|
Firstly, you MUST NEVER perform any filesystem operations while you have the doslist locked, as it will most likely end in a deadlock if your action causes a handler startup or other action that changes the doslist.
Calling any DOS functions is also unwise for that matter as they may take an innordinant amount of time to complete, and as of V53 the doslist lock still implies a Forbid(), which means that multitasking stops.
Better to do it this way; Make a struct MinList, call NewMinList() on it. Lock the doslist, use the flags; LDF_DEVICES|LDF_VOLUMES|LDF_READ.
Itterate, for each entry returned, allocate a minnode structure that holds the relevant data you want, namely dol_Type, dol_Port and some space for the dol_Name string. Something like this will do;
struct MyNode { struct MinNode my_Node; /* a simple struct Node */ int32 my_Type; /* holds the dol_Type DLT_xxx value */ struct MsgPort *my_Port; /* ptr to handler process port */ TEXT my_Name[256]; /* A C-String buffer for the BSTR name */ };
Then allocate one of these each time as sizeof(MyNode), and copy out the relevant fields. Then IExec->AddTail() the node to your minlist. Do this until you fall out, then unlock the doslist ASAP.
Now, if a DLT_VOLUME node has the same port address as a DLT_DEVICE, then you have found the matching nodes for a given mounted volume.
Just one caveat, DON'T actually use the port for anything other than the comparison, as a volume can "go away" at any moment.
Also, don't forget to IExec->RemHead() all your nodes and free them when you're finished..
|
|
|
|
Re: Wanted Ctorrent Betatester[V2.00 out]
|
Posted on: 2009/3/11 2:36
#114
|
Just popping in
|
@Antique
I just thought i'd stick my nose in here for a moment and mention a couple of issues observed and mentioned to me;
1) it would be nice if you included an Amiga version string in the next release, it's really inconvenient without one.
2) that DSI on startup is really annoying and you need to get a version out (even an interim one) that at least starts without a visit from the reaper, it's really unsettling.
3) Info being displayed in a plainer layout, specifically why there are two sets of up and down speeeds seperated by a comma. No-one seems to know why there are two lots of speed stats. Maybe a "newbie guide" could be deployed.
4) Why are the stats so unreliable, for example, if the first instance run says there are 3 seeders, 1 leecher and 5 peers, starting another instance on the exact same torrent may now report 8 seeders, 3 leechers and 10 peers while the first instance shown the same old values.
Anyway, there's a couple of things that I have found and some issues put to me from others.
Keep up the good work....
|
|
|
|
Re: Completely detached process
|
Posted on: 2009/3/10 9:57
#115
|
Just popping in
|
@orgin
Seeing you can see the problem area ahead of you, then make it so EVERY child can deallocate the seglist, by creating the children with the same seglist tag, but set the NP_FreeSegList,FALSE on child creation.
Then, use ProcessScan() at the exit point of the common child code to find out how many of your child processes are still running, and when the last one is exiting (ie; only 1 child) then delegate that child to be the process that frees the seglist by setting its proc->pr_Flags |= PRF_FREESEGLIST; bit, then simply return() to DOS.
There is example code in the ProcessScan() autodoc. See the "SignalMyChildProcsToExit" example code and just lose the Signal(), and use any of the child procs pr_ParentID to scan for other descendants, it will return the child process count.
Just beware of handlers being started up, therefore use a second tier check, i'd suggest a magic cookie in NP_UserData, or NP_EntryData or NP_ExitData or such, when starting the actual child processes.
Enjoy...
|
|
|
|
Re: Completely detached process
|
Posted on: 2009/3/10 3:40
#116
|
Just popping in
|
The subprocess is still running in the code space loaded for the parent. The parent exits, unloads the code, subprocess crashes. That's pretty well outlines your problem.
Two basic ways to fix this....
1) Use NP_Child tag and make the parent Wait()/WaitMsg() until the child exits, see; NP_NotifyOnDeathMessage and NP_NotifyOnDeathSigTask. Set up a message/signal and only allow the parent to leave only when the child notifies you of its death. However, this means that the parent must go to sleep until the child exits, which means that if the parent was a shell process, the CLI will be "dead" until the child ends.
2) If you wish to affect a complete detachment of the child and allow the parent to completely exit while allowing the child to continue execution in the old code space, then the resources that are shared by the child MUST also be detached.
This can be a little more complicated and not really for the beginner. Nevertheless, here's an outline of what needs to be done.
The easiest way is to call CreateNewProc() with no tags for the NP_Input,NP_Output,NP_Error, these will then open a default "NIL:" stream for the child (and 0 for the error stream). (and with NP_Child,FALSE)
With that taken care of, (here's the tricky part), because as the seglist is being shared, you must make sure it is not freed by the parent process on exit,
You can transfer ownership to the child process, so that it frees it on exit instead, so it is not done by the parent. To do this, you need to determine who loaded the original, this can be the shell or 'other'. If the shell loaded it, you need to stop it from unloading the command on exit.
Here's some pseudocode.....
============
BPTR seg = ZERO; struct CommandLineInterface *cli = IDOS->Cli(); if( cli ) { seg = cli->cli_Module; cli->cli_Module = ZERO; /* stop shell freeing the seg */ } else /* not a cli, try 'other' load methods */ { seg = IDOS->GetProcSegList(NULL,GPSLF_SEG); if( seg ) { struct Process *me = (struct Process *)FindTask(0); me->pr_Flags &= (~PRF_FREESEGLIST); } /* clear the flag for parent to free seglist */ }
if( seg ) /* did we find a loadsegged seglist ? */ { IDOS->CreateNewProcTags( NP_Entry, child_entry_func, /* entry() here */ NP_SegList, seg, /* free this seg on exit */ NP_FreeSegList,TRUE, /* make it so */ ... TAG_END); } else { PutStr("ERROR: Cannot find loaded seglist..\n"); }
NOTE WELL: You cannot call newlib functions in the child process unless you re-open the library within the child process itself, and set the childProc->pr_CLibData to the newlib base as there will be no default library context available to the child.
Better to just use the IDOS-> functions while inside the child process.
Also note that as the child is now responsible for freeing the seglist on exit, you MUST make sure the parent now exits BEFORE the child does, otherwise you will find yourself in the same situation.
|
|
|
|
Re: Stack usage tracking and stack size setting
|
Posted on: 2009/3/5 2:35
#117
|
Just popping in
|
@TSK
It does, to a point......
It will show you the amount of stack EVER written that contains a non-zero default value.
It would not include the full size of a local stack buffer of say 5000 bytes, that only had 1000 bytes written to it, the numbers would come up as 4000 bytes short in this case.
In other words, it calculates it from the first written non-zero value from the end of the frame, and shows that as the point of "usage" of the stack allocation.
However, for a guide it is close enough to be quite usefull.
|
|
|
|
Re: Subprocess launching and communication.
|
Posted on: 2008/10/2 2:43
#118
|
Just popping in
|
@krashan Quote: AmigaOS 4 autodocs do not say I can look at DeathMessage from the subprocess.
You can, I thought that was implied by the name of the field. The pointer is stored in pr_DeathMessage of the child process.
|
|
|
|
Re: Subprocess launching and communication.
|
Posted on: 2008/10/1 18:21
#119
|
Just popping in
|
@colinw
Allow me to rephrase my last reply.... I was in a hurry to go out for dinner at the time.
As the previous reply from Salass00 indicated, you get a free ExecBase pointer when you enter the child entry() function of the code pointed to by NP_Entry.
See the include file; dos/startup.h The child process starts up like all other processes in DOS do, just remember to declare the child process entry() just like that shown in startup.h. Just don't call the child entry function _start(), that symbol name is reserved for the initial entry point of the main executable.
If you wish to pass additional parameters to the child, you can use any of the "Spare" process fields of the child process, as long as they can be initialised in the call to CreateNewProc() via tags. For example; NP_EntryData, NP_ExitData, NP_FinalData, NP_UserData..... These are all available for your general usage, you can even pass pointers in these fields, such as a custom parameter structure or such like.
NB: The NP_EntryData and NP_ExitData tag values can be obtained by calling IDOS->GetEntryData() or IDOS->GetExitData() from within the child process. The other fields do not have accessor functions and would require that you call; struct Process *child = IExec->FindTask(0); from the child process to to get the child process pointer and to then access those other fields.
When the child is running in the shared code space of the parent, all globals are accessible, but remember that you have to take care with data that is shared by the two processes and employ some sort of arbitration when modifying any global values as the child is running independantly of the parent.
Now, as far as NP_Child tag goes, it causes DOS to put the parent process to sleep for a while if the child is still running when the parent attempts to exit. Once the child leaves, the parent is then allowed to exit fully and unload the program code. This tag should be specified when a child is depending on any resources of the parent process.
Just remember that NP_Child is only for non-persistent child processes, as the parent will not be able to terminate until the child does so first.
|
|
|
|
Re: Subprocess launching and communication.
|
Posted on: 2008/10/1 14:42
#120
|
Just popping in
|
@krashan
THe NP_Entry function has the ability to be passed a single parameter from the parent with the tag NP_EntryData.
That may be anything you wish, even a pointer to a compound structure....
|
|
|
|