revert between 56095 -> 55830 in arch
[AROS.git] / compiler / posixc / symlink.c
blob1ece2037eecf33919ac89713d97dd10dca3ef5d5
1 /*
2 Copyright © 2004-2012, The AROS Development Team. All rights reserved.
3 $Id$
5 POSIX.1-2008 function symlink().
6 */
8 #include <aros/debug.h>
10 #include <stdlib.h>
11 #include <proto/dos.h>
12 #include <errno.h>
13 #include "__upath.h"
15 /*****************************************************************************
17 NAME */
18 #include <unistd.h>
20 int symlink(
22 /* SYNOPSIS */
23 const char *oldpath,
24 const char *newpath)
26 /* FUNCTION
28 INPUTS
30 RESULT
32 NOTES
34 EXAMPLE
36 BUGS
38 SEE ALSO
40 INTERNALS
42 ******************************************************************************/
44 int retval = -1;
45 BPTR lock;
46 LONG ioerr = 0;
47 UBYTE *buffer;
48 int buffersize = 256;
50 if (!oldpath || !newpath) /*safety check */
52 errno = EFAULT;
53 return -1;
56 oldpath = __path_u2a(oldpath);
57 if(!oldpath)
58 return -1;
60 oldpath = strdup(oldpath);
61 if(!oldpath)
63 errno = ENOMEM;
64 return -1;
67 newpath = __path_u2a(newpath);
68 if (!newpath)
70 free((void*) oldpath);
71 return -1;
74 if((lock = Lock((STRPTR)oldpath, SHARED_LOCK)))
78 if(!(buffer = AllocVec(buffersize, MEMF_ANY)))
80 ioerr = ERROR_NO_FREE_STORE;
81 break;
84 /* Get the full path of oldpath */
85 if(NameFromLock(lock, buffer, buffersize))
87 if(MakeLink((STRPTR)newpath, (SIPTR)buffer, TRUE))
88 retval = 0;
89 else
91 ioerr = IoErr();
92 FreeVec(buffer);
93 break;
96 else if(IoErr() != ERROR_LINE_TOO_LONG)
98 ioerr = IoErr();
99 FreeVec(buffer);
100 break;
102 FreeVec(buffer);
103 buffersize *= 2;
105 while(retval != RETURN_OK);
106 UnLock(lock);
108 else
110 /* MakeLink can create symlinks to non-existing files or
111 directories. */
112 if(IoErr() == ERROR_OBJECT_NOT_FOUND)
114 /* In this case it may be difficult to get the full absolute
115 path, so we simply trust the caller here for now */
116 if(MakeLink((STRPTR)newpath, (SIPTR)oldpath, TRUE))
117 retval = 0;
118 else
119 ioerr = IoErr();
121 else
122 ioerr = IoErr();
124 free((void*) oldpath);
126 if(ioerr)
127 errno = __stdc_ioerr2errno(ioerr);
129 return retval;
130 } /* symlink */