Can someone point me (enlight) where to look (website, code, sdk docs,...) to add to poweroff SYNC feature (like in reboot cmd.)?
TIA
how to SYNC to inhibit all partitions
- salass00
- AmigaOS Core Developer
- Posts: 534
- Joined: Sat Jun 18, 2011 4:12 pm
- Location: Finland
- Contact:
Re: how to SYNC to inhibit all partitions
Essentially all you need to do is go through all the devices in the doslist and inhibit them.
The following code should do that:
Depending on how safe you want to be you could check for a failure of InhibitPort() function. If it returns FALSE and IDOS->IoErr() !=ERROR_ACTION_NOT_KNOWN then that means that the device couldn't inhibit because there was an error. In such a case you could if you wanted to set a flag and then afterwards uninhibit all the devices and not do the poweroff.
The following code should do that:
Code: Select all
static void Sync(void) {
const uint32 flags = LDF_READ|LDF_DEVICES;
struct DeviceNode *dn;
dn = IDOS->LockDosList(flags);
while ((dn = (struct DeviceNode *)IDOS->NextDosEntry((struct DosList *)dn, flags))) {
if (dn->dn_Port != NULL) {
/* Skip RAM Disk */
if (!strcmp((char *)BADDR(dn->dn_Name)+1, "RAM"))
continue;
/* Cause filesystem to flush all pending writes. */
/* Inhibit should do this as well but might be useful for old
filesystems that don't support inhibit? */
IDOS->FlushVolumePort(dn->dn_Port); /* Requires dos.library V53.90 */
/* Inhibit filesystem. */
IDOS->InhibitPort(dn->dn_Port, TRUE); /* Requires dos.library V53.88 */
}
}
IDOS->UnLockDosList(flags);
}
Re: how to SYNC to inhibit all partitions
Or he could just use C:Reboot SYNC...
Re: how to SYNC to inhibit all partitions
He wants to poweroff, not rebootZeroG wrote:Or he could just use C:Reboot SYNC...
- javierdlr
- Beta Tester
- Posts: 389
- Joined: Sun Jun 19, 2011 11:13 pm
- Location: Donostia (GUIPUZCOA) - Spain
- Contact:
Re: how to SYNC to inhibit all partitions
Thx it works fine your codesalass00 wrote:Essentially all you need to do is go through all the devices in the doslist and inhibit them.
..

Why are you using 'struct DeviceNode *dn;' instead of 'struct DosList *dl;' looking in autodocs 'IDOS->LockDosList()' result "should" be a DosList structure. Or am I mixing things (or too complicated for a non programmer guy :-O )
Thx again.
Hidden Text - Click to Show :
- salass00
- AmigaOS Core Developer
- Posts: 534
- Joined: Sat Jun 18, 2011 4:12 pm
- Location: Finland
- Contact:
Re: how to SYNC to inhibit all partitions
The DeviceNode struct is a specialised version of the DosList structure which applies only when the type field of the DosList is DLT_DEVICE. There are also others like VolumeNode for DLT_VOLUME and AssignNode for DLT_ASSIGN. The DosList structure just combines all of these into one structure using a union for the type specific fields.javierdlr wrote: Thx it works fine your codejust a question:
Why are you using 'struct DeviceNode *dn;' instead of 'struct DosList *dl;' looking in autodocs 'IDOS->LockDosList()' result "should" be a DosList structure. Or am I mixing things (or too complicated for a non programmer guy :-O )
You can also check out the comments on the structures in <dos/dosextens.h> as they explain this too.
- javierdlr
- Beta Tester
- Posts: 389
- Joined: Sun Jun 19, 2011 11:13 pm
- Location: Donostia (GUIPUZCOA) - Spain
- Contact:
Re: how to SYNC to inhibit all partitions
Hi, now using this code to SYNC, suing AllocDosObjectTags now:
Tried a couple of times and seems to work fine, any "difference"/"better" to use AllocDosObject() instead of previous (see first reply http://forum.hyperion-entertainment.biz ... 983#p20462) one?
Could I get a problem, 'cos now I strncmp 'RAM Disk:' instead of 'RAM:', maybe someone renamed 'RAM Disk:' to 'RAMDisk:' or alike.
TIA
Code: Select all
static void Sync(void) {
int32 result;
struct Node *nd = NULL;
struct InfoData id;
struct DevProc *dp = NULL;
struct List *list = IDOS->AllocDosObjectTags(DOS_VOLUMELIST,
ADO_Type, LDF_VOLUMES,
ADO_AddColon, TRUE,
TAG_END);
if(list)
{
for( nd = IExec->GetHead(list); nd; nd = IExec->GetSucc(nd) )
{
dp = IDOS->GetDeviceProc(nd->ln_Name, NULL);
if( !ILocale->StrnCmp(NULL, nd->ln_Name, "RAM Disk:", -1, SC_ASCII) ) continue; // Skip RAM Disk
result = IDOS->GetDiskInfoTags(GDI_StringNameInput, nd->ln_Name,
GDI_InfoData, &id,
TAG_END);
if(result)
{
if(id.id_DiskState == ID_DISKSTATE_WRITE_PROTECTED) continue;
// Cause filesystem to flush all pending writes.
// Inhibit should do this as well but might be useful for old
// filesystems that don't support Inhibit to use Flush
IDOS->FlushVolumePort(dp->dvp_Port); // Requires dos.library V53.90
IDOS->InhibitPort(dp->dvp_Port, TRUE); // Requires dos.library V53.88
}
}
IDOS->FreeDeviceProc(dp);
IDOS->FreeDosObject(DOS_VOLUMELIST,list);
}
}
Could I get a problem, 'cos now I strncmp 'RAM Disk:' instead of 'RAM:', maybe someone renamed 'RAM Disk:' to 'RAMDisk:' or alike.
TIA
- colinw
- AmigaOS Core Developer
- Posts: 218
- Joined: Mon Aug 15, 2011 10:20 am
- Location: Brisbane, QLD. Australia.
Re: how to SYNC to inhibit all partitions
Drop the ram disk test entirely, it's pointless, RAM will inhibit like all the others, so there's absolutely no point in doing that.javierdlr wrote:Hi, now using this code to SYNC, suing AllocDosObjectTags now:
Tried a couple of times and seems to work fine, any "difference"/"better" to use AllocDosObject() instead of previous one.
Could I get a problem, 'cos now I strncmp 'RAM Disk:' instead of 'RAM:', maybe someone renamed 'RAM Disk:' to 'RAMDisk:' or alike.
TIA
Also, drop the GetDiskInfo() test, it's also pointless, a write protected volume will still inhibit just fine.
You MUST test the result from GetDeviceProc(), it can return NULL.
You are doing it correctly using AllocDosObject() but be aware of the ADO_Type, LDF_VOLUMES all have DOS devices,
but not all LDF_DEVICES have filesystem volumes.
For what you are doing, LDF_VOLUMES is more correct because you probably are not interested in trying to kill things
like ENV: URL: TEXTCLIP: PIPE: APPDIR: etc....
Also, use IDOS->IsFileSystemPort( dp->dvp_Port ) as the final test for whether you should flush and inhibit this volume.
- javierdlr
- Beta Tester
- Posts: 389
- Joined: Sun Jun 19, 2011 11:13 pm
- Location: Donostia (GUIPUZCOA) - Spain
- Contact:
Re: how to SYNC to inhibit all partitions
THX Collin will change code and test it ASAP. THX again.
- colinw
- AmigaOS Core Developer
- Posts: 218
- Joined: Mon Aug 15, 2011 10:20 am
- Location: Brisbane, QLD. Australia.
Re: how to SYNC to inhibit all partitions
By the way, I only just noticed...
FreeDeviceproc() must be called for each GetDeviceProc(), INSIDE the volume list loop.
As it is shown above, it's returning the deviceproc for each volume and just orphaning the devproc memory,
except for the last one when it falls out of the loop and calls FreeDeviceProc().
FreeDeviceproc() must be called for each GetDeviceProc(), INSIDE the volume list loop.
As it is shown above, it's returning the deviceproc for each volume and just orphaning the devproc memory,
except for the last one when it falls out of the loop and calls FreeDeviceProc().