English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Language > Coders. C/C++

 
 
Thread Tools
Old 07 December 2015, 03:02   #1
tygre
Returning fan!

tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 769
Cannot get WBStartup struct when starting from Workbench (with VBCC)

Dear all!

I am running into a problem and I spent my afternoon trying to fix it. I want to get the path of my program no matter if it is run from a CLI or from the Workbench. I read lots of threads here and there but, in my code, the call to WaitPort(&(process->pr_MsgPort)); never ends when I double-click on the program's icon!

What am I doing wrong? What am I missing? It must be obvious but...
Thanks in advance!

Code:
/* Includes */

#include <stdio.h>
#include <stdlib.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <time.h>
#include <exec/execbase.h>
#include <workbench/startup.h>

#include "controlscli.h"
#include "controlsmui.h"
#include "fortify.h"
#include "version.h"



/* Constants and declarations */

int main(int, int **);

BPTR path;



/* Definitions */

BPTR path = 0;

int main(int argc, int **argv)
{
    CONST_STRPTR                        arguments_template = "MUI/S,VERSION/S";
    struct { long mui; long version; }  arguments_values   = { 0 };
    struct RDArgs                      *arguments          = NULL;
    int                                 result             = RETURN_ERROR;
    struct WBStartup                   *wbstartup          = NULL;
    struct Process                     *process            = NULL;
    struct CommandLineInterface        *cli                = NULL;
    BPTR                                file               = 0;

    srand(time(NULL));

    file = Open("CON:0/40/640/150/Output0/auto/close/wait", MODE_NEWFILE);
    process       = (struct Process *)FindTask(NULL);
    FPrintf(file, "process = %ld\n", process);
    FPrintf(file, "pr_CLI  = %ld\n", process->pr_CLI);
    if(process->pr_CLI == 0)
    {
        FPrintf(file, "Here1\n");
        WaitPort(&(process->pr_MsgPort));
        FPrintf(file, "Here2\n");
        wbstartup = (struct WBStartup *)GetMsg(&(process->pr_MsgPort));
        FPrintf(file, "wbstartup = %ld\n", wbstartup);
        process   = wbstartup->sm_Message.mn_ReplyPort->mp_SigTask;
    }
    else
    {
    }
    FPrintf(file, "process = %ld\n", process);
    cli           = BADDR(process->pr_CLI);
    FPrintf(file, "cli     = %ld\n", cli);
    path          = cli->cli_CommandDir;
    FPrintf(file, "path    = %ld\n", path);

    arguments = ReadArgs(arguments_template, (APTR)&arguments_values, NULL);
    if(arguments == NULL)
    {
        PrintFault(IoErr(), NULL);
        return RETURN_ERROR;
    }
    else if(arguments_values.version)
    {
        printf("%s\n", get_version_string());
        result = RETURN_OK;
    }
    else if(arguments_values.mui || argc == 0)
    {
        result = controls_mui();
    }
    else
    {
        result = controls_cli();
    }

    FreeArgs(arguments);
    return result;
}
PS. Forgot to mention that I am using VBCC 0.98 and would like my code to run in 3.x (or even 2.x) and newer... if possible?

Last edited by tygre; 07 December 2015 at 10:29. Reason: More information
tygre is offline  
Old 07 December 2015, 11:20   #2
hooverphonique
ex. demoscener "Bigmama"

 
Join Date: Jun 2012
Location: Fyn / Denmark
Posts: 1,144
does your program have an actual .info file or are you using "show all files" ?
hooverphonique is offline  
Old 07 December 2015, 11:34   #3
Toni Wilen
WinUAE developer
 
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 45
Posts: 24,072
You must not do any dos calls before WBStartup message has been retrieved, DOS packets and WBStartup use same message port.
Toni Wilen is offline  
Old 07 December 2015, 12:29   #4
thomas
Registered User
thomas's Avatar
 
Join Date: Jan 2002
Location: Germany
Posts: 6,086
Quote:
Originally Posted by tygre View Post
What am I missing? It must be obvious but...
Thanks in advance!

When your main() routine is called, all the WB handling has already been done by the standard startup code. The message has already been fetched, you won't get another one.

To distinct between CLI and WB usage in a standard main() routine, you can check argc. If it is 0, the program was called from WB and argv points to the wbstartup message. If argc is > 0 argv points to the standard C args.

Code:
#include <proto/dos.h>
#include <proto/intuition.h>
#include <workbench/startup.h>

int main (int argc,char **argv)
{
if (argc == 0)
	{
	struct WBStartup *wbmsg = (struct WBStartup *)argv;
	struct EasyStruct es = {
		sizeof(struct EasyStruct),
		0,
		"WB Example",
		"started from Workbench;\nprogram name = <%s>",
		"Ok"};
	ULONG idcmp = 0;
	EasyRequest (NULL,&es,&idcmp,wbmsg->sm_ArgList[0].wa_Name);
	}
else
	{
	Printf ("started from CLI; program name = <%s>\n",argv[0]);
	}
return (RETURN_OK);
}
compile with
Code:
vc wbtest1.c -o wbtest1 -lauto -lamiga


If you want to handle the WBStartup message yourself, you cannot use the standard startup code. Then you have to do everything yourself. Use -nostdlib switch to omit the standard startup code.

Code:
#define __NOLIBBASE__
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <workbench/startup.h>

__saveds int startup (__reg("a0") char *argstr,__reg("d0") long arglen)

{
struct Library *SysBase = *((struct Library **)4);
struct Process *pr = (struct Process *) FindTask (NULL);

if (!pr->pr_CLI)
	{
	struct WBStartup *wbmsg;
	struct Library *IntuitionBase;

	WaitPort (&pr->pr_MsgPort);
	wbmsg = (struct WBStartup *) GetMsg (&pr->pr_MsgPort);

	if (IntuitionBase = OpenLibrary ("intuition.library",36))
		{
		struct EasyStruct es = {
			sizeof(struct EasyStruct),
			0,
			"WB Example",
			"started from Workbench;\nprogram name = <%s>",
			"Ok"};
		ULONG idcmp = 0;

		EasyRequestArgs (NULL,&es,&idcmp,&wbmsg->sm_ArgList[0].wa_Name);

		CloseLibrary (IntuitionBase);
		}

	Forbid();
	ReplyMsg ((struct Message *)wbmsg);
	}
else
	{
	struct Library *DOSBase;
	if (DOSBase = OpenLibrary ("dos.library",36))
		{
		char name[256];
		APTR varargs[1];

		GetProgramName (name,sizeof(name));

		varargs[0] = name;
		VPrintf ("started from CLI; program name = <%s>\n",varargs);

		CloseLibrary (DOSBase);
		}
	}

return (RETURN_OK);
}
compile with
Code:
vc -nostdlib wbtest2.c -o wbtest2

Last edited by thomas; 07 December 2015 at 14:52.
thomas is offline  
Old 07 December 2015, 14:56   #5
tygre
Returning fan!

tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 769
Hi hooverphonique, Toni, and Thomas!

Thanks you all for your answers and your explanations!

Yes, my program has an icon but that should not make any difference, should it?

I will try again later today but, at one point, I had tried struct WBStartup *wbmsg = (struct WBStartup *)argv; and, IIRC, it returned a NULL pointer... but let me try again!

Will keep you posted and thanks again!
tygre is offline  
Old 08 December 2015, 04:29   #6
tygre
Returning fan!

tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 769
Hi again!

Ah, you were right of course

Using struct WBStartup *wbmsg = (struct WBStartup *)argv; works perfectly fine! My problem came from my (dumb?) use of WBRun: when using WBRun to run the command, wbmsg exists but the associated process is NULL.

Anyhow, now everything is great, thanks a lot!
tygre is offline  
Old 08 December 2015, 11:10   #7
hooverphonique
ex. demoscener "Bigmama"

 
Join Date: Jun 2012
Location: Fyn / Denmark
Posts: 1,144
Quote:
Originally Posted by tygre View Post
when using WBRun to run the command, wbmsg exists but the associated process is NULL.
you mean FindTask(NULL) returns NULL?
hooverphonique is offline  
Old 08 December 2015, 11:39   #8
thomas
Registered User
thomas's Avatar
 
Join Date: Jan 2002
Location: Germany
Posts: 6,086
That's impossible. No, he means this returns NULL (from his first listing):

Code:
process   = wbstartup->sm_Message.mn_ReplyPort->mp_SigTask;
thomas is offline  
Old 08 December 2015, 15:00   #9
tygre
Returning fan!

tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 769
@hooverphonique and @Thomas

Yes, exactly as Thomas says

It seems that WBLoad (part of CLICon) could solve this problem (and that this problem comes from WBRun, which may be fixed in a later version...)

Take care!
tygre is offline  
Old 08 December 2015, 15:22   #10
thomas
Registered User
thomas's Avatar
 
Join Date: Jan 2002
Location: Germany
Posts: 6,086
What do you need it for? It is (in the best case) the process of Workbench. There should be no reason to access it by an application.
thomas is offline  
Old 08 December 2015, 23:30   #11
tygre
Returning fan!

tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 769
Quote:
Originally Posted by thomas View Post
What do you need it for? It is (in the best case) the process of Workbench. There should be no reason to access it by an application.
Hi Thomas!

I was using it to actually test AmiModRadio from a CLI but as if running it from the Workbench... but now I realise that WBRun does not replace the real thing

Take well care
tygre is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Hard Blits under intuition & Gif To "struct BitMap" converter krabob Coders. Asm / Hardware 2 15 September 2014 17:25
struct Image mritter0 Coders. C/C++ 5 05 June 2014 02:36
Problem in wbstartup creates software failure demax support.Other 5 15 March 2008 12:53
Starting Games in Picasso96 Workbench Environment XenonMB support.WinUAE 8 13 September 2006 18:05
WBStartup in OS3.9... th4t1guy support.Apps 6 26 August 2003 23:40

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 04:26.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2020, vBulletin Solutions Inc.
Page generated in 0.08286 seconds with 14 queries