xref: /openbsd-src/gnu/usr.bin/perl/amigaos4/amigaos.c (revision 256a93a44f36679bee503f12e49566c2183f6181)
1b8851fccSafresh1 /* amigaos.c uses only amigaos APIs,
2b8851fccSafresh1  * as opposed to amigaio.c which mixes amigaos and perl APIs */
3b8851fccSafresh1 
4b8851fccSafresh1 #include <string.h>
5b8851fccSafresh1 
6b8851fccSafresh1 #include <sys/stat.h>
7b8851fccSafresh1 #include <unistd.h>
8b8851fccSafresh1 #include <assert.h>
9b8851fccSafresh1 
10b8851fccSafresh1 #include <errno.h>
11b8851fccSafresh1 #include <stdio.h>
12b8851fccSafresh1 #include <stdlib.h>
13b8851fccSafresh1 #if defined(__CLIB2__)
14b8851fccSafresh1 #  include <dos.h>
15b8851fccSafresh1 #endif
16b8851fccSafresh1 #if defined(__NEWLIB__)
17b8851fccSafresh1 #  include <amiga_platform.h>
18b8851fccSafresh1 #endif
19b8851fccSafresh1 #include <fcntl.h>
20b8851fccSafresh1 #include <ctype.h>
21b8851fccSafresh1 #include <stdarg.h>
22b8851fccSafresh1 #include <stdbool.h>
23b8851fccSafresh1 #undef WORD
24b8851fccSafresh1 #define WORD int16
25b8851fccSafresh1 
26b8851fccSafresh1 #include <dos/dos.h>
27b8851fccSafresh1 #include <proto/dos.h>
28b8851fccSafresh1 #include <proto/exec.h>
29b8851fccSafresh1 #include <proto/utility.h>
30b8851fccSafresh1 
31b8851fccSafresh1 #include "amigaos.h"
32b8851fccSafresh1 
33b8851fccSafresh1 struct UtilityIFace *IUtility = NULL;
34b8851fccSafresh1 
35b8851fccSafresh1 /***************************************************************************/
36b8851fccSafresh1 
OpenInterface(CONST_STRPTR libname,uint32 libver)37b8851fccSafresh1 struct Interface *OpenInterface(CONST_STRPTR libname, uint32 libver)
38b8851fccSafresh1 {
39b8851fccSafresh1         struct Library *base = IExec->OpenLibrary(libname, libver);
40b8851fccSafresh1         struct Interface *iface = IExec->GetInterface(base, "main", 1, NULL);
41b8851fccSafresh1         if (iface == NULL)
42b8851fccSafresh1         {
43b8851fccSafresh1                 // We should probably post some kind of error message here.
44b8851fccSafresh1 
45b8851fccSafresh1                 IExec->CloseLibrary(base);
46b8851fccSafresh1         }
47b8851fccSafresh1 
48b8851fccSafresh1         return iface;
49b8851fccSafresh1 }
50b8851fccSafresh1 
51b8851fccSafresh1 /***************************************************************************/
52b8851fccSafresh1 
CloseInterface(struct Interface * iface)53b8851fccSafresh1 void CloseInterface(struct Interface *iface)
54b8851fccSafresh1 {
55b8851fccSafresh1         if (iface != NULL)
56b8851fccSafresh1         {
57b8851fccSafresh1                 struct Library *base = iface->Data.LibBase;
58b8851fccSafresh1                 IExec->DropInterface(iface);
59b8851fccSafresh1                 IExec->CloseLibrary(base);
60b8851fccSafresh1         }
61b8851fccSafresh1 }
62b8851fccSafresh1 
63b8851fccSafresh1 BOOL __unlink_retries = FALSE;
64b8851fccSafresh1 
65b8851fccSafresh1 void ___makeenviron() __attribute__((constructor));
66b8851fccSafresh1 void ___freeenviron() __attribute__((destructor));
67b8851fccSafresh1 
68b8851fccSafresh1 void ___openinterfaces() __attribute__((constructor));
69b8851fccSafresh1 void ___closeinterfaces() __attribute__((destructor));
70b8851fccSafresh1 
___openinterfaces()71b8851fccSafresh1 void ___openinterfaces()
72b8851fccSafresh1 {
73b8851fccSafresh1         if (!IDOS)
74b8851fccSafresh1                 IDOS = (struct DOSIFace *)OpenInterface("dos.library", 53);
75b8851fccSafresh1         if (!IUtility)
76b8851fccSafresh1                 IUtility =
77b8851fccSafresh1                     (struct UtilityIFace *)OpenInterface("utility.library", 53);
78b8851fccSafresh1 }
79b8851fccSafresh1 
___closeinterfaces()80b8851fccSafresh1 void ___closeinterfaces()
81b8851fccSafresh1 {
82b8851fccSafresh1         CloseInterface((struct Interface *)IDOS);
83b8851fccSafresh1         CloseInterface((struct Interface *)IUtility);
84b8851fccSafresh1 }
85b8851fccSafresh1 int VARARGS68K araddebug(UBYTE *fmt, ...);
86b8851fccSafresh1 int VARARGS68K adebug(UBYTE *fmt, ...);
87b8851fccSafresh1 
88b8851fccSafresh1 #define __USE_RUNCOMMAND__
89b8851fccSafresh1 
90b8851fccSafresh1 char **myenviron = NULL;
91b8851fccSafresh1 char **origenviron = NULL;
92b8851fccSafresh1 
93b8851fccSafresh1 static void createvars(char **envp);
94b8851fccSafresh1 
95b8851fccSafresh1 struct args
96b8851fccSafresh1 {
97b8851fccSafresh1         BPTR seglist;
98b8851fccSafresh1         int stack;
99b8851fccSafresh1         char *command;
100b8851fccSafresh1         int length;
101b8851fccSafresh1         int result;
102b8851fccSafresh1         char **envp;
103b8851fccSafresh1 };
104b8851fccSafresh1 
__myrc(char * arg)105b8851fccSafresh1 int __myrc(__attribute__((unused))char *arg)
106b8851fccSafresh1 {
107b8851fccSafresh1         struct Task *thisTask = IExec->FindTask(0);
108b8851fccSafresh1         struct args *myargs = (struct args *)thisTask->tc_UserData;
109b8851fccSafresh1         if (myargs->envp)
110b8851fccSafresh1                 createvars(myargs->envp);
111b8851fccSafresh1         // adebug("%s %ld %s \n",__FUNCTION__,__LINE__,myargs->command);
112b8851fccSafresh1         myargs->result = IDOS->RunCommand(myargs->seglist, myargs->stack,
113b8851fccSafresh1                                           myargs->command, myargs->length);
114b8851fccSafresh1         return 0;
115b8851fccSafresh1 }
116b8851fccSafresh1 
myruncommand(BPTR seglist,int stack,char * command,int length,char ** envp)117b8851fccSafresh1 int32 myruncommand(
118b8851fccSafresh1     BPTR seglist, int stack, char *command, int length, char **envp)
119b8851fccSafresh1 {
120b8851fccSafresh1         struct args myargs;
121b8851fccSafresh1         struct Task *thisTask = IExec->FindTask(0);
122b8851fccSafresh1         struct Process *proc;
123b8851fccSafresh1 
124b8851fccSafresh1         // adebug("%s %ld  %s\n",__FUNCTION__,__LINE__,command?command:"NULL");
125b8851fccSafresh1 
126b8851fccSafresh1         myargs.seglist = seglist;
127b8851fccSafresh1         myargs.stack = stack;
128b8851fccSafresh1         myargs.command = command;
129b8851fccSafresh1         myargs.length = length;
130b8851fccSafresh1         myargs.result = -1;
131b8851fccSafresh1         myargs.envp = envp;
132b8851fccSafresh1 
133b8851fccSafresh1         if ((proc = IDOS->CreateNewProcTags(
134b8851fccSafresh1                         NP_Entry, __myrc, NP_Child, TRUE, NP_Input, IDOS->Input(),
135b8851fccSafresh1                         NP_Output, IDOS->Output(), NP_Error, IDOS->ErrorOutput(),
136b8851fccSafresh1                         NP_CloseInput, FALSE, NP_CloseOutput, FALSE, NP_CloseError,
137b8851fccSafresh1                         FALSE, NP_CopyVars, FALSE,
138b8851fccSafresh1 
139b8851fccSafresh1                         //           NP_StackSize,           ((struct Process
140b8851fccSafresh1                         //           *)myargs.parent)->pr_StackSize,
141b8851fccSafresh1                         NP_Cli, TRUE, NP_UserData, (int)&myargs,
142b8851fccSafresh1                         NP_NotifyOnDeathSigTask, thisTask, TAG_DONE)))
143b8851fccSafresh1 
144b8851fccSafresh1         {
145b8851fccSafresh1                 IExec->Wait(SIGF_CHILD);
146b8851fccSafresh1         }
147b8851fccSafresh1         return myargs.result;
148b8851fccSafresh1 }
149b8851fccSafresh1 
mystrdup(const char * s)150b8851fccSafresh1 char *mystrdup(const char *s)
151b8851fccSafresh1 {
152b8851fccSafresh1         char *result = NULL;
153b8851fccSafresh1         size_t size;
154b8851fccSafresh1 
155b8851fccSafresh1         size = strlen(s) + 1;
156b8851fccSafresh1 
157b8851fccSafresh1         if ((result = (char *)IExec->AllocVecTags(size, TAG_DONE)))
158b8851fccSafresh1         {
159b8851fccSafresh1                 memmove(result, s, size);
160b8851fccSafresh1         }
161b8851fccSafresh1         return result;
162b8851fccSafresh1 }
163b8851fccSafresh1 
164b8851fccSafresh1 unsigned int pipenum = 0;
165b8851fccSafresh1 
pipe(int filedes[2])166b8851fccSafresh1 int pipe(int filedes[2])
167b8851fccSafresh1 {
168b8851fccSafresh1         char pipe_name[1024];
169b8851fccSafresh1 
170b8851fccSafresh1 //   adebug("%s %ld \n",__FUNCTION__,__LINE__);
171b8851fccSafresh1 #ifdef USE_TEMPFILES
172b8851fccSafresh1         sprintf(pipe_name, "/T/%x.%08lx", pipenum++, IUtility->GetUniqueID());
173b8851fccSafresh1 #else
174b8851fccSafresh1         sprintf(pipe_name, "/PIPE/%x%08lx/4096/0", pipenum++,
175b8851fccSafresh1                 IUtility->GetUniqueID());
176b8851fccSafresh1 #endif
177b8851fccSafresh1 
178b8851fccSafresh1         /*      printf("pipe: %s \n", pipe_name);*/
179b8851fccSafresh1 
180b8851fccSafresh1         filedes[1] = open(pipe_name, O_WRONLY | O_CREAT);
181b8851fccSafresh1         filedes[0] = open(pipe_name, O_RDONLY);
182b8851fccSafresh1         if (filedes[0] == -1 || filedes[1] == -1)
183b8851fccSafresh1         {
184b8851fccSafresh1                 if (filedes[0] != -1)
185b8851fccSafresh1                         close(filedes[0]);
186b8851fccSafresh1                 if (filedes[1] != -1)
187b8851fccSafresh1                         close(filedes[1]);
188b8851fccSafresh1                 return -1;
189b8851fccSafresh1         }
190b8851fccSafresh1         /*      printf("filedes %d %d\n", filedes[0],
191b8851fccSafresh1          * filedes[1]);fflush(stdout);*/
192b8851fccSafresh1 
193b8851fccSafresh1         return 0;
194b8851fccSafresh1 }
195b8851fccSafresh1 
fork(void)196b8851fccSafresh1 int fork(void)
197b8851fccSafresh1 {
198b8851fccSafresh1         fprintf(stderr, "Can not bloody fork\n");
199b8851fccSafresh1         errno = ENOMEM;
200b8851fccSafresh1         return -1;
201b8851fccSafresh1 }
202b8851fccSafresh1 
wait(int * status)203b8851fccSafresh1 int wait(__attribute__((unused))int *status)
204b8851fccSafresh1 {
205b8851fccSafresh1         fprintf(stderr, "No wait try waitpid instead\n");
206b8851fccSafresh1         errno = ECHILD;
207b8851fccSafresh1         return -1;
208b8851fccSafresh1 }
209b8851fccSafresh1 
convert_path_a2u(const char * filename)210b8851fccSafresh1 char *convert_path_a2u(const char *filename)
211b8851fccSafresh1 {
212b8851fccSafresh1         struct NameTranslationInfo nti;
213b8851fccSafresh1 
214b8851fccSafresh1         if (!filename)
215b8851fccSafresh1         {
216b8851fccSafresh1                 return 0;
217b8851fccSafresh1         }
218b8851fccSafresh1 
219b8851fccSafresh1         __translate_amiga_to_unix_path_name(&filename, &nti);
220b8851fccSafresh1 
221b8851fccSafresh1         return mystrdup(filename);
222b8851fccSafresh1 }
convert_path_u2a(const char * filename)223b8851fccSafresh1 char *convert_path_u2a(const char *filename)
224b8851fccSafresh1 {
225b8851fccSafresh1         struct NameTranslationInfo nti;
226b8851fccSafresh1 
227b8851fccSafresh1         if (!filename)
228b8851fccSafresh1         {
229b8851fccSafresh1                 return 0;
230b8851fccSafresh1         }
231b8851fccSafresh1 
232b8851fccSafresh1         if (strcmp(filename, "/dev/tty") == 0)
233b8851fccSafresh1         {
234b8851fccSafresh1                 return mystrdup("CONSOLE:");
235b8851fccSafresh1                 ;
236b8851fccSafresh1         }
237b8851fccSafresh1 
238b8851fccSafresh1         __translate_unix_to_amiga_path_name(&filename, &nti);
239b8851fccSafresh1 
240b8851fccSafresh1         return mystrdup(filename);
241b8851fccSafresh1 }
242b8851fccSafresh1 
243b8851fccSafresh1 struct SignalSemaphore environ_sema;
244b8851fccSafresh1 struct SignalSemaphore popen_sema;
245b8851fccSafresh1 
246b8851fccSafresh1 
amigaos4_init_environ_sema()247b8851fccSafresh1 void amigaos4_init_environ_sema()
248b8851fccSafresh1 {
249b8851fccSafresh1         IExec->InitSemaphore(&environ_sema);
250b8851fccSafresh1         IExec->InitSemaphore(&popen_sema);
251b8851fccSafresh1 }
252b8851fccSafresh1 
amigaos4_obtain_environ()253b8851fccSafresh1 void amigaos4_obtain_environ()
254b8851fccSafresh1 {
255b8851fccSafresh1         IExec->ObtainSemaphore(&environ_sema);
256b8851fccSafresh1 }
257b8851fccSafresh1 
amigaos4_release_environ()258b8851fccSafresh1 void amigaos4_release_environ()
259b8851fccSafresh1 {
260b8851fccSafresh1         IExec->ReleaseSemaphore(&environ_sema);
261b8851fccSafresh1 }
262b8851fccSafresh1 
createvars(char ** envp)263b8851fccSafresh1 static void createvars(char **envp)
264b8851fccSafresh1 {
265b8851fccSafresh1         if (envp)
266b8851fccSafresh1         {
267b8851fccSafresh1                 /* Set a local var to indicate to any subsequent sh that it is
268b8851fccSafresh1                 * not
269b8851fccSafresh1                 * the top level shell and so should only inherit local amigaos
270b8851fccSafresh1                 * vars */
271b8851fccSafresh1                 IDOS->SetVar("ABCSH_IMPORT_LOCAL", "TRUE", 5, GVF_LOCAL_ONLY);
272b8851fccSafresh1 
273b8851fccSafresh1                 amigaos4_obtain_environ();
274b8851fccSafresh1 
275b8851fccSafresh1                 envp = myenviron;
276b8851fccSafresh1 
277b8851fccSafresh1                 while ((envp != NULL) && (*envp != NULL))
278b8851fccSafresh1                 {
279b8851fccSafresh1                         int len;
280b8851fccSafresh1                         char *var;
281b8851fccSafresh1                         char *val;
282b8851fccSafresh1                         if ((len = strlen(*envp)))
283b8851fccSafresh1                         {
284b8851fccSafresh1                                 if ((var = (char *)IExec->AllocVecTags(len + 1, AVT_ClearWithValue,0,TAG_DONE)))
285b8851fccSafresh1                                 {
286b8851fccSafresh1                                         strcpy(var, *envp);
287b8851fccSafresh1 
288b8851fccSafresh1                                         val = strchr(var, '=');
289b8851fccSafresh1                                         if (val)
290b8851fccSafresh1                                         {
291b8851fccSafresh1                                                 *val++ = '\0';
292b8851fccSafresh1                                                 if (*val)
293b8851fccSafresh1                                                 {
294b8851fccSafresh1                                                         IDOS->SetVar(
295b8851fccSafresh1                                                             var, val,
296b8851fccSafresh1                                                             strlen(val) + 1,
297b8851fccSafresh1                                                             GVF_LOCAL_ONLY);
298b8851fccSafresh1                                                 }
299b8851fccSafresh1                                         }
300b8851fccSafresh1                                         IExec->FreeVec(var);
301b8851fccSafresh1                                 }
302b8851fccSafresh1                         }
303b8851fccSafresh1                         envp++;
304b8851fccSafresh1                 }
305b8851fccSafresh1                 amigaos4_release_environ();
306b8851fccSafresh1         }
307b8851fccSafresh1 }
308b8851fccSafresh1 
309b8851fccSafresh1 struct command_data
310b8851fccSafresh1 {
311b8851fccSafresh1         STRPTR args;
312b8851fccSafresh1         BPTR seglist;
313b8851fccSafresh1         struct Task *parent;
314b8851fccSafresh1 };
315b8851fccSafresh1 
316b8851fccSafresh1 
myexecvp(bool isperlthread,const char * filename,char * argv[])317b8851fccSafresh1 int myexecvp(bool isperlthread, const char *filename, char *argv[])
318b8851fccSafresh1 {
319b8851fccSafresh1         //	adebug("%s %ld
320b8851fccSafresh1         //%s\n",__FUNCTION__,__LINE__,filename?filename:"NULL");
321b8851fccSafresh1         /* if there's a slash or a colon consider filename a path and skip
322b8851fccSafresh1          * search */
323b8851fccSafresh1         int res;
324b8851fccSafresh1         char *name = NULL;
325b8851fccSafresh1         char *pathpart = NULL;
326b8851fccSafresh1         if ((strchr(filename, '/') == NULL) && (strchr(filename, ':') == NULL))
327b8851fccSafresh1         {
328b8851fccSafresh1                 const char *path;
329b8851fccSafresh1                 const char *p;
330b8851fccSafresh1                 size_t len;
331b8851fccSafresh1                 struct stat st;
332b8851fccSafresh1 
333b8851fccSafresh1                 if (!(path = getenv("PATH")))
334b8851fccSafresh1                 {
335b8851fccSafresh1                         path = ".:/bin:/usr/bin:/c";
336b8851fccSafresh1                 }
337b8851fccSafresh1 
338b8851fccSafresh1                 len = strlen(filename) + 1;
339b8851fccSafresh1                 name = (char *)IExec->AllocVecTags(strlen(path) + len, AVT_ClearWithValue,0,AVT_Type,MEMF_SHARED,TAG_DONE);
340b8851fccSafresh1                 pathpart = (char *)IExec->AllocVecTags(strlen(path) + 1, AVT_ClearWithValue,0,AVT_Type,MEMF_SHARED,TAG_DONE);
341b8851fccSafresh1                 p = path;
342b8851fccSafresh1                 do
343b8851fccSafresh1                 {
344b8851fccSafresh1                         path = p;
345b8851fccSafresh1 
346b8851fccSafresh1                         if (!(p = strchr(path, ':')))
347b8851fccSafresh1                         {
348b8851fccSafresh1                                 p = strchr(path, '\0');
349b8851fccSafresh1                         }
350b8851fccSafresh1 
351b8851fccSafresh1                         memcpy(pathpart, path, p - path);
352b8851fccSafresh1                         pathpart[p - path] = '\0';
353b8851fccSafresh1                         if (!(strlen(pathpart) == 0))
354b8851fccSafresh1                         {
355b8851fccSafresh1                                 sprintf(name, "%s/%s", pathpart, filename);
356b8851fccSafresh1                         }
357b8851fccSafresh1                         else
358b8851fccSafresh1                                 sprintf(name, "%s", filename);
359b8851fccSafresh1 
360b8851fccSafresh1                         if ((stat(name, &st) == 0) && (S_ISREG(st.st_mode)))
361b8851fccSafresh1                         {
362b8851fccSafresh1                                 /* we stated it and it's a regular file */
363b8851fccSafresh1                                 /* let's boogie! */
364b8851fccSafresh1                                 filename = name;
365b8851fccSafresh1                                 break;
366b8851fccSafresh1                         }
367b8851fccSafresh1 
368b8851fccSafresh1                 }
369b8851fccSafresh1                 while (*p++ != '\0');
370b8851fccSafresh1         }
371b8851fccSafresh1 
372b8851fccSafresh1         res = myexecve(isperlthread, filename, argv, myenviron);
373b8851fccSafresh1 
374b8851fccSafresh1         if(name)
375b8851fccSafresh1         {
376b8851fccSafresh1                 IExec->FreeVec((APTR)name);
377b8851fccSafresh1                 name = NULL;
378b8851fccSafresh1         }
379b8851fccSafresh1         if(pathpart)
380b8851fccSafresh1         {
381b8851fccSafresh1                 IExec->FreeVec((APTR)pathpart);
382b8851fccSafresh1                 pathpart = NULL;
383b8851fccSafresh1         }
384b8851fccSafresh1         return res;
385b8851fccSafresh1 }
386b8851fccSafresh1 
myexecv(bool isperlthread,const char * path,char * argv[])387b8851fccSafresh1 int myexecv(bool isperlthread, const char *path, char *argv[])
388b8851fccSafresh1 {
389b8851fccSafresh1         return myexecve(isperlthread, path, argv, myenviron);
390b8851fccSafresh1 }
391b8851fccSafresh1 
myexecl(bool isperlthread,const char * path,...)392b8851fccSafresh1 int myexecl(bool isperlthread, const char *path, ...)
393b8851fccSafresh1 {
394b8851fccSafresh1         va_list va;
395b8851fccSafresh1         char *argv[1024]; /* 1024 enough? let's hope so! */
396b8851fccSafresh1         int i = 0;
397b8851fccSafresh1         // adebug("%s %ld\n",__FUNCTION__,__LINE__);
398b8851fccSafresh1 
399b8851fccSafresh1         va_start(va, path);
400b8851fccSafresh1         i = 0;
401b8851fccSafresh1 
402b8851fccSafresh1         do
403b8851fccSafresh1         {
404b8851fccSafresh1                 argv[i] = va_arg(va, char *);
405b8851fccSafresh1         }
406b8851fccSafresh1         while (argv[i++] != NULL);
407b8851fccSafresh1 
408b8851fccSafresh1         va_end(va);
409b8851fccSafresh1         return myexecve(isperlthread, path, argv, myenviron);
410b8851fccSafresh1 }
411b8851fccSafresh1 
pause(void)412b8851fccSafresh1 int pause(void)
413b8851fccSafresh1 {
414b8851fccSafresh1         fprintf(stderr, "Pause not implemented\n");
415b8851fccSafresh1 
416b8851fccSafresh1         errno = EINTR;
417b8851fccSafresh1         return -1;
418b8851fccSafresh1 }
419b8851fccSafresh1 
size_env(struct Hook * hook,APTR userdata,struct ScanVarsMsg * message)420b8851fccSafresh1 uint32 size_env(struct Hook *hook, __attribute__((unused))APTR userdata, struct ScanVarsMsg *message)
421b8851fccSafresh1 {
422b8851fccSafresh1         if (strlen(message->sv_GDir) <= 4)
423b8851fccSafresh1         {
424b8851fccSafresh1                 hook->h_Data = (APTR)(((uint32)hook->h_Data) + 1);
425b8851fccSafresh1         }
426b8851fccSafresh1         return 0;
427b8851fccSafresh1 }
428b8851fccSafresh1 
copy_env(struct Hook * hook,APTR userdata,struct ScanVarsMsg * message)429b8851fccSafresh1 uint32 copy_env(struct Hook *hook, __attribute__((unused))APTR userdata, struct ScanVarsMsg *message)
430b8851fccSafresh1 {
431b8851fccSafresh1         if (strlen(message->sv_GDir) <= 4)
432b8851fccSafresh1         {
433b8851fccSafresh1                 char **env = (char **)hook->h_Data;
434b8851fccSafresh1                 uint32 size =
435b8851fccSafresh1                     strlen(message->sv_Name) + 1 + message->sv_VarLen + 1 + 1;
436b8851fccSafresh1                 char *buffer = (char *)IExec->AllocVecTags((uint32)size,AVT_ClearWithValue,0,TAG_DONE);
437b8851fccSafresh1 
438b8851fccSafresh1 
439b8851fccSafresh1                 snprintf(buffer, size - 1, "%s=%s", message->sv_Name,
440b8851fccSafresh1                          message->sv_Var);
441b8851fccSafresh1 
442b8851fccSafresh1                 *env = buffer;
443b8851fccSafresh1                 env++;
444b8851fccSafresh1                 hook->h_Data = env;
445b8851fccSafresh1         }
446b8851fccSafresh1         return 0;
447b8851fccSafresh1 }
448b8851fccSafresh1 
___makeenviron()449b8851fccSafresh1 void ___makeenviron()
450b8851fccSafresh1 {
451b8851fccSafresh1         struct Hook *hook = (struct Hook *)IExec->AllocSysObjectTags(ASOT_HOOK,TAG_DONE);
452b8851fccSafresh1 
453b8851fccSafresh1         if(hook)
454b8851fccSafresh1         {
455b8851fccSafresh1                 char varbuf[8];
456b8851fccSafresh1                 uint32 flags = 0;
457b8851fccSafresh1 
458b8851fccSafresh1                 struct DOSIFace *myIDOS =
459b8851fccSafresh1                     (struct DOSIFace *)OpenInterface("dos.library", 53);
460b8851fccSafresh1                 if (myIDOS)
461b8851fccSafresh1                 {
462b8851fccSafresh1                         uint32 size = 0;
463b8851fccSafresh1                         if (myIDOS->GetVar("ABCSH_IMPORT_LOCAL", varbuf, 8,
464b8851fccSafresh1                                            GVF_LOCAL_ONLY) > 0)
465b8851fccSafresh1                         {
466b8851fccSafresh1                                 flags = GVF_LOCAL_ONLY;
467b8851fccSafresh1                         }
468b8851fccSafresh1                         else
469b8851fccSafresh1                         {
470b8851fccSafresh1                                 flags = GVF_GLOBAL_ONLY;
471b8851fccSafresh1                         }
472b8851fccSafresh1 
473b8851fccSafresh1                         hook->h_Entry = size_env;
474b8851fccSafresh1                         hook->h_Data = 0;
475b8851fccSafresh1 
476b8851fccSafresh1                         myIDOS->ScanVars(hook, flags, 0);
477b8851fccSafresh1                         size  = ((uint32)hook->h_Data) + 1;
478b8851fccSafresh1 
479b8851fccSafresh1                         myenviron = (char **)IExec->AllocVecTags(size *
480b8851fccSafresh1                                     sizeof(char **),
481b8851fccSafresh1                                     AVT_ClearWithValue,0,TAG_DONE);
482b8851fccSafresh1                         origenviron = myenviron;
483b8851fccSafresh1                         if (!myenviron)
484b8851fccSafresh1                         {
485b8851fccSafresh1                                 IExec->FreeSysObject(ASOT_HOOK,hook);
486b8851fccSafresh1                                 CloseInterface((struct Interface *)myIDOS);
487b8851fccSafresh1                                 return;
488b8851fccSafresh1                         }
489b8851fccSafresh1                         hook->h_Entry = copy_env;
490b8851fccSafresh1                         hook->h_Data = myenviron;
491b8851fccSafresh1 
492b8851fccSafresh1                         myIDOS->ScanVars(hook, flags, 0);
493b8851fccSafresh1                         IExec->FreeSysObject(ASOT_HOOK,hook);
494b8851fccSafresh1                         CloseInterface((struct Interface *)myIDOS);
495b8851fccSafresh1                 }
496b8851fccSafresh1         }
497b8851fccSafresh1 }
498b8851fccSafresh1 
___freeenviron()499b8851fccSafresh1 void ___freeenviron()
500b8851fccSafresh1 {
501b8851fccSafresh1         char **i;
502b8851fccSafresh1         /* perl might change environ, it puts it back except for ctrl-c */
503b8851fccSafresh1         /* so restore our own copy here */
504b8851fccSafresh1         struct DOSIFace *myIDOS =
505b8851fccSafresh1             (struct DOSIFace *)OpenInterface("dos.library", 53);
506b8851fccSafresh1         if (myIDOS)
507b8851fccSafresh1         {
508b8851fccSafresh1                 myenviron = origenviron;
509b8851fccSafresh1 
510b8851fccSafresh1                 if (myenviron)
511b8851fccSafresh1                 {
512b8851fccSafresh1                         for (i = myenviron; *i != NULL; i++)
513b8851fccSafresh1                         {
514b8851fccSafresh1                                 IExec->FreeVec(*i);
515b8851fccSafresh1                         }
516b8851fccSafresh1                         IExec->FreeVec(myenviron);
517b8851fccSafresh1                         myenviron = NULL;
518b8851fccSafresh1                 }
519b8851fccSafresh1                 CloseInterface((struct Interface *)myIDOS);
520b8851fccSafresh1         }
521b8851fccSafresh1 }
522b8851fccSafresh1 
523b8851fccSafresh1 
524*256a93a4Safresh1 /* Work around for clib2 fstat */
525b8851fccSafresh1 #ifndef S_IFCHR
526b8851fccSafresh1 #define S_IFCHR 0x0020000
527b8851fccSafresh1 #endif
528b8851fccSafresh1 
529b8851fccSafresh1 #define SET_FLAG(u, v) ((void)((u) |= (v)))
530b8851fccSafresh1 
afstat(int fd,struct stat * statb)531b8851fccSafresh1 int afstat(int fd, struct stat *statb)
532b8851fccSafresh1 {
533b8851fccSafresh1         int result;
534b8851fccSafresh1         BPTR fh;
535b8851fccSafresh1         int mode;
536b8851fccSafresh1         BOOL input;
537b8851fccSafresh1         /* In the first instance pass it to fstat */
538b8851fccSafresh1         // adebug("fd %ld ad %ld\n",fd,amigaos_get_file(fd));
539b8851fccSafresh1 
540b8851fccSafresh1         if ((result = fstat(fd, statb) >= 0))
541b8851fccSafresh1                 return result;
542b8851fccSafresh1 
543b8851fccSafresh1         /* Now we've got a file descriptor but we failed to stat it */
544b8851fccSafresh1         /* Could be a nil: or could be a std#? */
545b8851fccSafresh1 
546b8851fccSafresh1         /* if get_default_file fails we had a dud fd so return failure */
547b8851fccSafresh1 #if !defined(__CLIB2__)
548b8851fccSafresh1 
549b8851fccSafresh1         fh = amigaos_get_file(fd);
550b8851fccSafresh1 
551b8851fccSafresh1         /* if nil: return failure*/
552b8851fccSafresh1         if (fh == 0)
553b8851fccSafresh1                 return -1;
554b8851fccSafresh1 
555b8851fccSafresh1         /* Now compare with our process Input() Output() etc */
556b8851fccSafresh1         /* if these were regular files sockets or pipes we had already
557b8851fccSafresh1          * succeeded */
558b8851fccSafresh1         /* so we can guess they a character special console.... I hope */
559b8851fccSafresh1 
560b8851fccSafresh1         struct ExamineData *data;
561b8851fccSafresh1         char name[120];
562b8851fccSafresh1         name[0] = '\0';
563b8851fccSafresh1 
564b8851fccSafresh1         data = IDOS->ExamineObjectTags(EX_FileHandleInput, fh, TAG_END);
565b8851fccSafresh1         if (data != NULL)
566b8851fccSafresh1         {
567b8851fccSafresh1 
568b8851fccSafresh1                 IUtility->Strlcpy(name, data->Name, sizeof(name));
569b8851fccSafresh1 
570b8851fccSafresh1                 IDOS->FreeDosObject(DOS_EXAMINEDATA, data);
571b8851fccSafresh1         }
572b8851fccSafresh1 
573b8851fccSafresh1         // adebug("ad %ld '%s'\n",amigaos_get_file(fd),name);
574b8851fccSafresh1         mode = S_IFCHR;
575b8851fccSafresh1 
576b8851fccSafresh1         if (fh == IDOS->Input())
577b8851fccSafresh1         {
578b8851fccSafresh1                 input = TRUE;
579b8851fccSafresh1                 SET_FLAG(mode, S_IRUSR);
580b8851fccSafresh1                 SET_FLAG(mode, S_IRGRP);
581b8851fccSafresh1                 SET_FLAG(mode, S_IROTH);
582b8851fccSafresh1         }
583b8851fccSafresh1         else if (fh == IDOS->Output() || fh == IDOS->ErrorOutput())
584b8851fccSafresh1         {
585b8851fccSafresh1                 input = FALSE;
586b8851fccSafresh1                 SET_FLAG(mode, S_IWUSR);
587b8851fccSafresh1                 SET_FLAG(mode, S_IWGRP);
588b8851fccSafresh1                 SET_FLAG(mode, S_IWOTH);
589b8851fccSafresh1         }
590b8851fccSafresh1         else
591b8851fccSafresh1         {
592b8851fccSafresh1                 /* we got a filehandle not handle by fstat or the above */
593b8851fccSafresh1                 /* most likely it's NIL: but lets check */
594b8851fccSafresh1                 struct ExamineData *exd = NULL;
595b8851fccSafresh1                 if ((exd = IDOS->ExamineObjectTags(EX_FileHandleInput, fh,
596b8851fccSafresh1                                                    TAG_DONE)))
597b8851fccSafresh1                 {
598b8851fccSafresh1                         BOOL isnil = FALSE;
599b8851fccSafresh1                         if (exd->Type ==
600b8851fccSafresh1                                 (20060920)) // Ugh yes I know nasty.....
601b8851fccSafresh1                         {
602b8851fccSafresh1                                 isnil = TRUE;
603b8851fccSafresh1                         }
604b8851fccSafresh1                         IDOS->FreeDosObject(DOS_EXAMINEDATA, exd);
605b8851fccSafresh1                         if (isnil)
606b8851fccSafresh1                         {
607b8851fccSafresh1                                 /* yep we got NIL: */
608b8851fccSafresh1                                 SET_FLAG(mode, S_IRUSR);
609b8851fccSafresh1                                 SET_FLAG(mode, S_IRGRP);
610b8851fccSafresh1                                 SET_FLAG(mode, S_IROTH);
611b8851fccSafresh1                                 SET_FLAG(mode, S_IWUSR);
612b8851fccSafresh1                                 SET_FLAG(mode, S_IWGRP);
613b8851fccSafresh1                                 SET_FLAG(mode, S_IWOTH);
614b8851fccSafresh1                         }
615b8851fccSafresh1                         else
616b8851fccSafresh1                         {
617b8851fccSafresh1                                 IExec->DebugPrintF(
618b8851fccSafresh1                                     "unhandled filehandle in afstat()\n");
619b8851fccSafresh1                                 return -1;
620b8851fccSafresh1                         }
621b8851fccSafresh1                 }
622b8851fccSafresh1         }
623b8851fccSafresh1 
624*256a93a4Safresh1         memzero(statb, sizeof(statb));
625b8851fccSafresh1 
626b8851fccSafresh1         statb->st_mode = mode;
627b8851fccSafresh1 
628b8851fccSafresh1 #endif
629b8851fccSafresh1         return 0;
630b8851fccSafresh1 }
631b8851fccSafresh1 
amigaos_get_file(int fd)632b8851fccSafresh1 BPTR amigaos_get_file(int fd)
633b8851fccSafresh1 {
634b8851fccSafresh1         BPTR fh = (BPTR)NULL;
635b8851fccSafresh1         if (!(fh = _get_osfhandle(fd)))
636b8851fccSafresh1         {
637b8851fccSafresh1                 switch (fd)
638b8851fccSafresh1                 {
639b8851fccSafresh1                 case 0:
640b8851fccSafresh1                         fh = IDOS->Input();
641b8851fccSafresh1                         break;
642b8851fccSafresh1                 case 1:
643b8851fccSafresh1                         fh = IDOS->Output();
644b8851fccSafresh1                         break;
645b8851fccSafresh1                 case 2:
646b8851fccSafresh1                         fh = IDOS->ErrorOutput();
647b8851fccSafresh1                         break;
648b8851fccSafresh1                 default:
649b8851fccSafresh1                         break;
650b8851fccSafresh1                 }
651b8851fccSafresh1         }
652b8851fccSafresh1         return fh;
653b8851fccSafresh1 }
654b8851fccSafresh1 
655b8851fccSafresh1 /*########################################################################*/
656b8851fccSafresh1 
657b8851fccSafresh1 #define LOCK_START 0xFFFFFFFFFFFFFFFELL
658b8851fccSafresh1 #define LOCK_LENGTH 1LL
659b8851fccSafresh1 
660b8851fccSafresh1 // No wait forever option so lets wait for a loooong time.
661b8851fccSafresh1 #define TIMEOUT 0x7FFFFFFF
662b8851fccSafresh1 
amigaos_flock(int fd,int oper)663b8851fccSafresh1 int amigaos_flock(int fd, int oper)
664b8851fccSafresh1 {
665b8851fccSafresh1         BPTR fh;
666b8851fccSafresh1         int32 success = -1;
667b8851fccSafresh1 
668b8851fccSafresh1         if (!(fh = amigaos_get_file(fd)))
669b8851fccSafresh1         {
670b8851fccSafresh1                 errno = EBADF;
671b8851fccSafresh1                 return -1;
672b8851fccSafresh1         }
673b8851fccSafresh1 
674b8851fccSafresh1         switch (oper)
675b8851fccSafresh1         {
676b8851fccSafresh1         case LOCK_SH:
677b8851fccSafresh1         {
678b8851fccSafresh1                 if (IDOS->LockRecord(fh, LOCK_START, LOCK_LENGTH,
679b8851fccSafresh1                                      REC_SHARED | RECF_DOS_METHOD_ONLY,
680b8851fccSafresh1                                      TIMEOUT))
681b8851fccSafresh1                 {
682b8851fccSafresh1                         success = 0;
683b8851fccSafresh1                 }
684b8851fccSafresh1                 break;
685b8851fccSafresh1         }
686b8851fccSafresh1         case LOCK_EX:
687b8851fccSafresh1         {
688b8851fccSafresh1                 if (IDOS->LockRecord(fh, LOCK_START, LOCK_LENGTH,
689b8851fccSafresh1                                      REC_EXCLUSIVE | RECF_DOS_METHOD_ONLY,
690b8851fccSafresh1                                      TIMEOUT))
691b8851fccSafresh1                 {
692b8851fccSafresh1                         success = 0;
693b8851fccSafresh1                 }
694b8851fccSafresh1                 break;
695b8851fccSafresh1         }
696b8851fccSafresh1         case LOCK_SH | LOCK_NB:
697b8851fccSafresh1         {
698b8851fccSafresh1                 if (IDOS->LockRecord(fh, LOCK_START, LOCK_LENGTH,
699b8851fccSafresh1                                      REC_SHARED_IMMED | RECF_DOS_METHOD_ONLY,
700b8851fccSafresh1                                      TIMEOUT))
701b8851fccSafresh1                 {
702b8851fccSafresh1                         success = 0;
703b8851fccSafresh1                 }
704b8851fccSafresh1                 else
705b8851fccSafresh1                 {
706b8851fccSafresh1                         errno = EWOULDBLOCK;
707b8851fccSafresh1                 }
708b8851fccSafresh1                 break;
709b8851fccSafresh1         }
710b8851fccSafresh1         case LOCK_EX | LOCK_NB:
711b8851fccSafresh1         {
712b8851fccSafresh1                 if (IDOS->LockRecord(fh, LOCK_START, LOCK_LENGTH,
713b8851fccSafresh1                                      REC_EXCLUSIVE_IMMED | RECF_DOS_METHOD_ONLY,
714b8851fccSafresh1                                      TIMEOUT))
715b8851fccSafresh1                 {
716b8851fccSafresh1                         success = 0;
717b8851fccSafresh1                 }
718b8851fccSafresh1                 else
719b8851fccSafresh1                 {
720b8851fccSafresh1                         errno = EWOULDBLOCK;
721b8851fccSafresh1                 }
722b8851fccSafresh1                 break;
723b8851fccSafresh1         }
724b8851fccSafresh1         case LOCK_UN:
725b8851fccSafresh1         {
726b8851fccSafresh1                 if (IDOS->UnLockRecord(fh, LOCK_START, LOCK_LENGTH))
727b8851fccSafresh1                 {
728b8851fccSafresh1                         success = 0;
729b8851fccSafresh1                 }
730b8851fccSafresh1                 break;
731b8851fccSafresh1         }
732b8851fccSafresh1         default:
733b8851fccSafresh1         {
734b8851fccSafresh1                 errno = EINVAL;
735b8851fccSafresh1                 return -1;
736b8851fccSafresh1         }
737b8851fccSafresh1         }
738b8851fccSafresh1         return success;
739b8851fccSafresh1 }
740