MakeLink() HARD

This forum is for general developer support questions.
User avatar
mritter0
Posts: 214
Joined: Mon Aug 25, 2014 9:41 pm
Location: Bettendorf, IA, USA

MakeLink() HARD

Post by mritter0 »

I am trying to use IDOS->MakeLink(). No problem with soft, but hard is giving me an issue:

Code: Select all

IDOS->MakeLink("RAM:test",(STRPTR)"RAM:T/WEx_Ver",LINK_SOFT)
works fine.

For hard links:

Code: Select all

			if ((MakeLinkLock=IDOS->Lock("RAM:T/WEx_Ver",ACCESS_READ)))
			{
				if (!IDOS->MakeLink("RAM:test",(APTR)MakeLinkLock,LINK_HARD))
				{
					SAK_IOErr=IDOS->IoErr();
					SAK_IOError(Objects[OID_WINDOW],MainWindow,RequesterTitle,REQIMAGE_ERROR,0,SAK_IOErr,SAK_LocaleString(MSG_DOS_ERROR_MESSAGE),SAK_LocaleString(MSG_CONTINUE));
				}
				else
					Success=TRUE;

				IDOS->UnLock(MakeLinkLock);
			}
			else
			{
				SAK_IOErr=IDOS->IoErr();
				SAK_IOError(Objects[OID_WINDOW],MainWindow,RequesterTitle,REQIMAGE_ERROR,0,SAK_IOErr,SAK_LocaleString(MSG_DOS_ERROR_MESSAGE),SAK_LocaleString(MSG_CONTINUE));
			}
Ends up pointing to "RAM Disk:Wex_Ver". The T drawer gets dropped.

RAM:test2 -> Workbench:Internet/graphics/ProbAnim
points to "RAM Disk:". Everything dropped.

There are no error messages.


EDIT: Just to make sure, after doing the IDOS->Lock() I did IDOS->NameFromLock(), it is correct.
Workbench Explorer - A better way to browse drawers
User avatar
javierdlr
Beta Tester
Beta Tester
Posts: 389
Joined: Sun Jun 19, 2011 10:13 pm
Location: Donostia (GUIPUZCOA) - Spain
Contact:

Re: MakeLink() HARD

Post by javierdlr »

Just created using your code a small test and here it doesn't fail (aos4.1fe beta system)

Code: Select all

#list
a.out                        160882 ----rwed Hoy       11:57:13
bar.c                           803 ----rwed Hoy       11:56:46
Clipboards                      Dir ----rwed Hoy       11:55:18
T                               Dir ----rwed Hoy       11:57:13
..
#list T/
Directorio "T" a Domingo 04-Jun-17
7za                         2740220 ----rwed Hoy       11:56:18
#a.out 
#list
foo                         2740220 ----rwed Hoy       11:57:18
> RAM Disk:T/7za
a.out                        160882 ----rwed Hoy       11:57:13
bar.c                           803 ----rwed Hoy       11:56:46
Clipboards                      Dir ----rwed Hoy       11:55:18
T                               Dir ----rwed Hoy       11:57:18
#
bar.c

Code: Select all

#include <proto/exec.h>
#include <proto/dos.h>

int main(void)
{
	BPTR MakeLinkLock;
	BOOL Success = FALSE;

	if( (MakeLinkLock=IDOS->Lock("RAM:T/7za",ACCESS_READ)) ) {
		if( !IDOS->MakeLink("RAM:foo",(APTR)MakeLinkLock,LINK_HARD) ) {
IDOS->Printf("ERROR in IDOS->MakeLink()\n");
			//SAK_IOErr=IDOS->IoErr();
			//SAK_IOError(Objects[OID_WINDOW],MainWindow,RequesterTitle,REQIMAGE_ERROR,0,SAK_IOErr,SAK_LocaleString(MSG_DOS_ERROR_MESSAGE),SAK_LocaleString(MSG_CONTINUE));
		}
		else {
			Success = TRUE;
		}

		IDOS->UnLock(MakeLinkLock);
	}
	else {
IDOS->Printf("ERROR in IDOS->Lock()\n");
		//SAK_IOErr=IDOS->IoErr();
		//SAK_IOError(Objects[OID_WINDOW],MainWindow,RequesterTitle,REQIMAGE_ERROR,0,SAK_IOErr,SAK_LocaleString(MSG_DOS_ERROR_MESSAGE),SAK_LocaleString(MSG_CONTINUE));
	}

	return( (int)Success );
}
Tested under AOS4.1FE upd1 no problems either:

Code: Select all

5.PRUEBAS:> gcc bar.c -lauto -Wall -gstabs
5.PRUEBAS:> copy SDH1:Misc/7za ram:T/
5.PRUEBAS:> a.out 
5.PRUEBAS:> list ram:
Directorio "ram:" a Domingo 04-Jun-17
foo                         2740220 ----rwed Hoy       12:15:11
> RAM Disk:T/7za
Disk.info                     43766 ----rwed Hoy       12:14:08
> ENVARC:Sys/def_RAM.info
Clipboards                      Dir ----rwed Hoy       12:14:06
T                               Dir ----rwed Hoy       12:15:08
2 ficheros - 2718K bytes - 2 directorios - 179 bloques usados
5.PRUEBAS:> 
Maybe you're having some issued/problems in your program with volumes having blank space ("Ram Disk")?
I see it only happens in WEx. How do you retrive/get "link string" (in WEx's comment column)?
User avatar
colinw
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 207
Joined: Mon Aug 15, 2011 9:20 am
Location: Brisbane, QLD. Australia.

Re: MakeLink() HARD

Post by colinw »

MakeLink() will fail if the link already exists. You should get: ERROR_OBJECT_EXISTS.
MakeLink( ,LINK_HARD) will likely fail with any version of SFS filesystem. It only supports softlinks.
MakeLink( ,LINK_HARD) has been tested on FFS7, NGF0 and RAM1 filesystems by me, it does definately work.
User avatar
javierdlr
Beta Tester
Beta Tester
Posts: 389
Joined: Sun Jun 19, 2011 10:13 pm
Location: Donostia (GUIPUZCOA) - Spain
Contact:

Re: MakeLink() HARD

Post by javierdlr »

Using dos_lib autdoc example I have no problmes with the full link name:

Code: Select all

#bar 
ERROR in IDOS->MakeLink() (already exists)
filename=bar
file hardlink=foo points to 7za [RAM Disk:T/7za]
dirname=Clipboards
dirname=T
So looks you're doing something wrong in your code :-/
Look into dos_lib's autodoc EXD_IS_LINK examples.
User avatar
mritter0
Posts: 214
Joined: Mon Aug 25, 2014 9:41 pm
Location: Bettendorf, IA, USA

Re: MakeLink() HARD

Post by mritter0 »

After seeing Javier's results, and more testing, my code is working. But confused by the results.

RAM:hard -> RAM:T/WEx_Ver
is my test.

Make hard link in program. Quit. In shell, list ram:. Link is correct.
Open my program, link does not show as hard link, just as the file it points to. (Soft links show correctly.)
Quit. List ram:. Hard link is gone. Just the link name with no destination path.

Delete and make new, done both in Shell and my program.
Filer doesn't show the correct hard link path. My program doesn't show the correct hard link path. In shell, List does.

Delete and make new, done both in Shell and my program.
Double click on link in Filer, it opens a file requester. Double click on it in my program, it shows the correct file (text file in MultiViewer). List in Shell, destination path gone.

Even if I make the hard link in Shell, open my program, browse ram: (Not touch the link), quit, list ram:, destination is gone. It's like my program is breaking the link.

Code: Select all

	if ((context=IDOS->ObtainDirContextTags(
		EX_LockInput,					lock,
		EX_DataFields,					EXF_ALL,
	TAG_DONE)))
	{
		while((dat=IDOS->ExamineDir(context)))
		{
			FoundLink=FALSE;

			if (EXD_IS_LINK(dat))		/* all links - check this first ! */
			{
				FoundLink=TRUE;

				if (EXD_IS_SOFTLINK(dat))		/* a FFS style softlink */
				{
				}
				else		/* hard or alt link to */
				{		/* a file or directory */
				}
			}
			else if (EXD_IS_FILE(dat))		/* a file */
			{
			}
			else if (EXD_IS_DIRECTORY(dat))		/* a directory */
			{
			}
........
Then I look at dat->Link. Then check that if it is a file or drawer.

X5000 NGFS.
Workbench Explorer - A better way to browse drawers
User avatar
mritter0
Posts: 214
Joined: Mon Aug 25, 2014 9:41 pm
Location: Bettendorf, IA, USA

Re: MakeLink() HARD

Post by mritter0 »

Colinw,

Yes, the system can make hard links. But it looks like it can't identify them yet?
Workbench Explorer - A better way to browse drawers
User avatar
colinw
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 207
Joined: Mon Aug 15, 2011 9:20 am
Location: Brisbane, QLD. Australia.

Re: MakeLink() HARD

Post by colinw »

mritter0 wrote:Colinw,
Yes, the system can make hard links. But it looks like it can't identify them yet?
I just tested it again with my test executable, it does definately work with the latest dos.library,
you didn't say what version you are using, it may have issues that have subsequently been fixed.

Code: Select all

8.RAM Disk:__testdir> examinedir ""
harddirlink                HARDDIR LINK -->  dir2  [RAM Disk:__testdir/dir2]
hardfilelink               HARDFILE LINK -->  file2  [RAM Disk:__testdir/file2]
softdirlink                SOFT LINK  -->  dir1  [RAM Disk:__testdir/dir1]
softfilelink               SOFT LINK  -->  CURRDIR:file1  [RAM Disk:__testdir/file1]  
dir2                       DIRECTORY 
dir1                       DIRECTORY 
file2                      FILE         Size 50
file1                      FILE         Size 50

(*)  The first result after -->  shows exd->Link contents.
(**) Square brackets show the result from NameFromLock()
I'm not sure how old your ExamineDir function autodocs in the SDK are, but it has been updated with a lot more
example code since earlier versions, so here is some relevant info from the latest one, I hope this helps resolve
your issue, if not reply back.

===============================================================================
* Linked Objects:
* When performing a directory scan using this function, the link entries
* in the listing will appear as soft or hard links, optionally,
* the examinedata->Link field will show the target name if that flag
* option is enabled. (EXF_LINK)
*
* Softlinks are resolved by DOS and may point to targets on other volumes.
* Hardlinks are resolved by the filesystem itself and are limited to
* target objects on the same volume as the links.
*
* Softlinks can be "broken", in that the target may no longer exist at
* the target specification. Hardlinks cannot be in a "broken" state.
*
* Softlinked directories can point to a target directory above the
* links directory, thereby causing an infinite recursive loop.
* All DOS API functions use a softlink counter and limit the number of
* softlinks in any path to a maximum of 15 (currently), if that is
* exceeded the function will fail with error code; ERROR_TOO_MANY_LEVELS.
*
* Hardlinked directories cannot have targets created that point to a
* level above the link directory, this means they cannot cause a loop.
* However, this protection MAY NOT be implemented with older packet based
* filesystems, so be carefull when recursively scanning a directory,
* or better still, don't enter any linked directory unless specifically
* told to do so, and then, only do it once.
*
*
* Softlink Targets:
* Always set EX_DoCurrentDir,TRUE tag in the ObtainDirContext() call when
* testing softlinks, this sets the current directory correctly for the
* ExamineObject() call which is used to obtain target object information.
* Softlink targets specifications in Examinedata->Link are usually link
* directory relative paths, but can instead contain information which
* specifies a path to another volume, that volume may or may not be
* currently mounted, so it is recommended that DOS requesters be disabled
* during the ExamineObject() call to prevent the appearance of the
* "Please Insert Volume..." requester. See also; SetProcWindow().
* If you got what you wanted, you should display the target data and type
* of object in the directory listing like Workbench, the ASL file requester,
* the Dir and List commands, etc. do.
*
* Hardlink Targets:
* Hardlinks are automatically handled by the filesystem, other than being
* identified by the examinedata->Type, they behave just like real files
* and directories. For purely semantical reasons, the filesystem will
* copy the target object name (no DOS path) into the examinedata->Link
* buffer, if that flag option is enabled. (EXF_LINK).
* This string cannot be used to resolve the hardlink target path.
* To obtain a fully qualified DOS path to the target of a hardlink,
* Lock() the examinedata->Name and call the [Dev]NameFromLock() function,
* for additional target information, call ExamineObject() using the same
* lock, don't forget to UnLock() it afterwards.
===============================================================================
User avatar
mritter0
Posts: 214
Joined: Mon Aug 25, 2014 9:41 pm
Location: Bettendorf, IA, USA

Re: MakeLink() HARD

Post by mritter0 »

Got it all figured out. Thanks Colin!

Just so I am clear: the first time I scan a drawer and find a hard link, it shows up as a hard link. The next time it shows not as a link, but as the actual destination item (file or drawer). Is that the correct behavior? So it looks seemless? It opens the correct item still.
Workbench Explorer - A better way to browse drawers
User avatar
colinw
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 207
Joined: Mon Aug 15, 2011 9:20 am
Location: Brisbane, QLD. Australia.

Re: MakeLink() HARD

Post by colinw »

mritter0 wrote:Got it all figured out. Thanks Colin!
Just so I am clear: the first time I scan a drawer and find a hard link, it shows up as a hard link.
The next time it shows not as a link, but as the actual destination item (file or drawer).
Is that the correct behavior?
No, it is not, every time you scan a given directory, links appear as links, files as files, dirs as dirs.
There is no "next time something is different" mode.

Where you are getting confused appears to be what you are doing with the link.
The operation of a link is supposed to be automatic and transparent to the caller, so, if you encounter a link,
soft or hard, and you try and Lock() or Open() it by name, that act in itself is what causes it to be resolved
to the target object. So; Lock("mylinkname") -> NameFromLock() = "target_object_name".
The Lock() function itself caused the link to be resolved to the target object.

You cannot Lock() the link name and expect information about the link itself, it really has none, it's not a file or dir,
it is only a redirect to the actual target object it points to, or is supposed to point to.

There are only two ways to "see" an actual link entry on a filesystem and obtain ExamineData for it, and not get
information about the target object instead, and only one way if you are not a V54 dos.library beta tester.
That is done by calling ExamineDir() on the parent directory where the link lives, like you normally do when scanning
a directory, or if you are using V54 of dos.library, there is a new tag for ExamineObject() that will return the same
information as the ExamineDir() call did, but without having to scan through the entire directory.

I hope this helps.
Reply again if you still have problems.
PS: You still didn't mention what dos.library version you are using.
User avatar
mritter0
Posts: 214
Joined: Mon Aug 25, 2014 9:41 pm
Location: Bettendorf, IA, USA

Re: MakeLink() HARD

Post by mritter0 »

I figured out my mistake. I had all the code correct, but I was testing it in RAM: for ease. I totally forgot it has to be on a NGFS system. It works as it should on my Workbench partition. Stays as a link with each scan.

X5000 dos.library 53.158

Thanks for your patience.
Workbench Explorer - A better way to browse drawers
Post Reply