Commit | Line | Data |
2986a63f |
1 | |
2 | /* |
3 | * Copyright © 2001 Novell, Inc. All Rights Reserved. |
4 | * |
5 | * You may distribute under the terms of either the GNU General Public |
6 | * License or the Artistic License, as specified in the README file. |
7 | * |
8 | */ |
9 | |
10 | /* |
11 | * FILENAME : nw5.c |
12 | * DESCRIPTION : Definitions for the redefined functions for NetWare. |
13 | * Author : SGP, HYAK |
14 | * Date : January 2001. |
15 | * |
16 | */ |
17 | |
18 | |
19 | |
acfe0abc |
20 | #include <perl.h> // For dTHX, etc. |
2986a63f |
21 | #include "nwpipe.h" |
22 | |
23 | |
24 | // This was added since the compile failed saying "undefined P_WAIT" |
25 | // when USE_ITHREADS was commented in the makefile |
26 | #ifndef P_WAIT |
27 | #define P_WAIT 0 |
28 | #endif |
29 | |
30 | #ifndef P_NOWAIT |
31 | #define P_NOWAIT 1 |
32 | #endif |
33 | |
34 | // The array is used to store pointer to the memory allocated to the TempPipeFile structure everytime |
35 | // a call to the function, nw_Popen. If a simple variable is used, everytime the memory is allocated before |
36 | // the previously allocated memory is freed, the pointer will get overwritten and the previous memory allocations |
37 | // are lost! Only the most recent one will get freed when calls are made to nw_Pclose. |
38 | // By using the array and the iPopenCount to index the array, all memory are freed! |
39 | |
40 | // The size of the array indicates the limit on the no of times the nw_Popen function can be called (and |
41 | // memory allocted) from within a script through backtick operators! |
42 | // This is arbitrarily set to MAX_PIPE_RECURSION=256 which indicates there can be 256 nested backtick operators possible! |
43 | PTEMPPIPEFILE ptpf1[MAX_PIPE_RECURSION] = {'\0'}; |
44 | int iPopenCount = 0; |
45 | FILE* File1[MAX_PIPE_RECURSION] = {'\0'}; |
46 | |
47 | |
48 | /** |
49 | General: |
50 | |
51 | In this code, wherever there is a FILE *, the error condition is checked; and only if the FILE * is TRUE, |
52 | then the corresponding operation is done. Otherwise the error value is returned. |
53 | This is done because the file operations like "open" in the Perl code returns the FILE *, |
54 | returning a valid value if the file is found or NULL when the particular file is not found. |
55 | Now, if the return value is NULL, then an operation say "fgets", "fopen" etc. using this this NULL value |
56 | for FILE * will abend the server. If the check is made then an operation on a non existing file |
57 | does not abend the server. |
58 | **/ |
59 | |
60 | void |
61 | nw_abort(void) |
62 | { |
63 | abort(); // Terminate the NLM application abnormally. |
64 | return; |
65 | } |
66 | |
67 | int |
68 | nw_access(const char *path, int mode) |
69 | { |
70 | return access(path, mode); |
71 | } |
72 | |
73 | int |
74 | nw_chmod(const char *path, int mode) |
75 | { |
76 | return chmod(path, mode); |
77 | } |
78 | |
79 | void |
80 | nw_clearerr(FILE *pf) |
81 | { |
82 | if(pf) |
83 | clearerr(pf); |
84 | } |
85 | |
86 | int |
87 | nw_close(int fd) |
88 | { |
89 | return close(fd); |
90 | } |
91 | |
92 | nw_closedir(DIR *dirp) |
93 | { |
94 | return (closedir(dirp)); |
95 | } |
96 | |
97 | void |
98 | nw_setbuf(FILE *pf, char *buf) |
99 | { |
100 | if(pf) |
101 | setbuf(pf, buf); |
102 | } |
103 | |
104 | int |
105 | nw_setmode(FILE *fp, int mode) |
106 | { |
f355267c |
107 | /** |
108 | // Commented since a few abends were happening in fnFpSetMode |
2986a63f |
109 | int *dummy = 0; |
110 | return(fnFpSetMode(fp, mode, dummy)); |
f355267c |
111 | **/ |
112 | |
113 | int handle = -1; |
114 | errno = 0; |
115 | |
116 | handle = fileno(fp); |
117 | if (errno) |
118 | { |
119 | errno = 0; |
120 | return -1; |
121 | } |
122 | return setmode(handle, mode); |
2986a63f |
123 | } |
124 | |
125 | int |
126 | nw_setvbuf(FILE *pf, char *buf, int type, size_t size) |
127 | { |
128 | if(pf) |
129 | return setvbuf(pf, buf, type, size); |
130 | else |
131 | return -1; |
132 | } |
133 | |
134 | |
135 | unsigned int |
136 | nw_sleep(unsigned int t) |
137 | { |
138 | delay(t*1000); // Put the thread to sleep for 't' seconds. Initially 't' is passed in milliseconds. |
139 | return 0; |
140 | } |
141 | |
142 | int |
143 | nw_spawnvp(int mode, char *cmdname, char **argv) |
144 | { |
145 | // There is no pass-around environment on NetWare so we throw that |
146 | // argument away for now. |
147 | |
148 | // The function "spawnvp" does not work in all situations. Loading |
149 | // edit.nlm seems to work, for example, but the name of the file |
150 | // to edit does not appear to get passed correctly. Another problem |
151 | // is that on Netware, P_WAIT does not really work reliably. It only |
152 | // works with NLMs built to use CLIB (according to Nile Thayne). |
153 | // NLMs such as EDIT that are written directly to the system have no |
154 | // way of running synchronously from another process. The whole |
155 | // architecture on NetWare seems pretty busted, so we just support it |
156 | // as best we can. |
157 | // |
158 | // The spawnvp function only launches NLMs, it will not execute a command; |
159 | // the NetWare "system" function is used for that purpose. Unfortunately, "system" |
160 | // always returns success whether the command is successful or not or even |
161 | // if the command was not found! To avoid ambiguity--you can have both an |
162 | // NLM named "perl" and a system command named "perl"--we need to |
163 | // force perl scripts to carry the word "load" when loading an NLM. This |
164 | // might be clearer anyway. |
165 | |
166 | int ret = 0; |
167 | int argc = 0; |
168 | |
169 | |
170 | if (stricmp(cmdname, LOAD_COMMAND) == 0) |
171 | { |
172 | if (argv[1] != NULL) |
173 | ret = spawnvp(mode, argv[1], &argv[1]); |
174 | } |
175 | else |
176 | { |
177 | int i=0; |
178 | while (argv[i] != '\0') |
179 | i++; |
180 | argc = i; |
181 | |
182 | fnSystemCommand(argv, argc); |
183 | } |
184 | |
185 | return ret; |
186 | } |
187 | |
188 | int |
189 | nw_execv(char *cmdname, char **argv) |
190 | { |
191 | return spawnvp(P_WAIT, cmdname, (char **)argv); |
192 | } |
193 | |
194 | |
195 | int |
196 | nw_execvp(char *cmdname, char **argv) |
197 | { |
198 | return nw_spawnvp(P_WAIT, cmdname, (char **)argv); |
199 | } |
200 | |
201 | int |
202 | nw_stat(const char *path, struct stat *sbuf) |
203 | { |
204 | return (stat(path, sbuf)); |
205 | } |
206 | |
207 | FILE * |
208 | nw_stderr(void) |
209 | { |
210 | return (stderr); |
211 | } |
212 | |
213 | FILE * |
214 | nw_stdin(void) |
215 | { |
216 | return (stdin); |
217 | } |
218 | |
219 | FILE * |
220 | nw_stdout() |
221 | { |
222 | return (stdout); |
223 | } |
224 | |
225 | long |
226 | nw_telldir(DIR *dirp) |
227 | { |
acfe0abc |
228 | dTHX; |
4d76e4b4 |
229 | Perl_croak(aTHX_ "The telldir() function is not implemented on NetWare\n"); |
2986a63f |
230 | return 0l; |
231 | } |
232 | |
233 | int |
234 | nw_times(struct tms *timebuf) |
235 | { |
236 | clock_t now = clock(); |
237 | |
238 | timebuf->tms_utime = now; |
239 | timebuf->tms_stime = 0; |
240 | timebuf->tms_cutime = 0; |
241 | timebuf->tms_cstime = 0; |
242 | |
243 | return 0; |
244 | } |
245 | |
246 | FILE* |
247 | nw_tmpfile(void) |
248 | { |
249 | return tmpfile(); |
250 | } |
251 | |
252 | int |
253 | nw_uname(struct utsname *name) |
254 | { |
255 | return(uname(name)); |
256 | } |
257 | |
258 | int |
259 | nw_ungetc(int c, FILE *pf) |
260 | { |
261 | if(pf) |
262 | return ungetc(c, pf); |
263 | else |
264 | return -1; |
265 | } |
266 | |
267 | int |
268 | nw_unlink(const char *filename) |
269 | { |
270 | return(unlink(filename)); |
271 | } |
272 | |
273 | int |
274 | nw_utime(const char *filename, struct utimbuf *times) |
275 | { |
276 | return(utime(filename, times)); |
277 | } |
278 | |
279 | int |
280 | nw_vfprintf(FILE *fp, const char *format, va_list args) |
281 | { |
282 | if(fp) |
283 | return (vfprintf(fp, format, args)); |
284 | else |
285 | return -1; |
286 | } |
287 | |
288 | int |
289 | nw_wait(int *status) |
290 | { |
291 | return 0; |
292 | } |
293 | |
294 | int |
295 | nw_waitpid(int pid, int *status, int flags) |
296 | { |
297 | return 0; |
298 | } |
299 | |
300 | int |
301 | nw_write(int fd, const void *buf, unsigned int cnt) |
302 | { |
303 | return write(fd, buf, cnt); |
304 | } |
305 | |
306 | char * |
307 | nw_crypt(const char *txt, const char *salt) |
308 | { |
acfe0abc |
309 | dTHX; |
2986a63f |
310 | |
311 | #ifdef HAVE_DES_FCRYPT |
312 | dTHR; |
313 | return des_fcrypt(txt, salt, w32_crypt_buffer); |
314 | #else |
4d76e4b4 |
315 | Perl_croak(aTHX_ "The crypt() function is not implemented on NetWare\n"); |
2986a63f |
316 | return Nullch; |
317 | #endif |
318 | } |
319 | |
320 | int |
321 | nw_dup(int fd) |
322 | { |
323 | return dup(fd); |
324 | } |
325 | |
326 | int |
327 | nw_dup2(int fd1,int fd2) |
328 | { |
329 | return dup2(fd1,fd2); |
330 | } |
331 | |
332 | void* |
333 | nw_dynaload(const char* filename) |
334 | { |
335 | return NULL; |
336 | } |
337 | |
338 | int |
339 | nw_fclose(FILE *pf) |
340 | { |
341 | if(pf) |
342 | return (fclose(pf)); |
343 | else |
344 | return -1; |
345 | } |
346 | |
347 | FILE * |
348 | nw_fdopen(int handle, const char *mode) |
349 | { |
350 | return(fdopen(handle, mode)); |
351 | } |
352 | |
353 | int |
354 | nw_feof(FILE *fp) |
355 | { |
356 | if(fp) |
357 | return (feof(fp)); |
358 | else |
359 | return -1; |
360 | } |
361 | |
362 | int |
363 | nw_ferror(FILE *fp) |
364 | { |
365 | if(fp) |
366 | return (ferror(fp)); |
367 | else |
368 | return -1; |
369 | } |
370 | |
371 | |
372 | int |
373 | nw_fflush(FILE *pf) |
374 | { |
375 | if(pf) |
376 | return fflush(pf); |
377 | else |
378 | return -1; |
379 | } |
380 | |
381 | int |
382 | nw_fgetpos(FILE *pf, fpos_t *p) |
383 | { |
384 | if(pf) |
385 | return fgetpos(pf, p); |
386 | else |
387 | return -1; |
388 | } |
389 | |
390 | char* |
391 | nw_fgets(char *s, int n, FILE *pf) |
392 | { |
393 | if(pf) |
394 | return(fgets(s, n, pf)); |
395 | else |
396 | return NULL; |
397 | } |
398 | |
399 | int |
400 | nw_fileno(FILE *pf) |
401 | { |
402 | if(pf) |
403 | return fileno(pf); |
404 | else |
405 | return -1; |
406 | } |
407 | |
408 | int |
409 | nw_flock(int fd, int oper) |
410 | { |
4d76e4b4 |
411 | dTHX; |
412 | Perl_croak(aTHX_ "The flock() function is not implemented on NetWare\n"); |
2986a63f |
413 | return 0; |
414 | } |
415 | |
416 | |
417 | FILE * |
418 | nw_fopen(const char *filename, const char *mode) |
419 | { |
420 | return (fopen(filename, mode)); |
421 | } |
422 | |
423 | int |
424 | nw_fputc(int c, FILE *pf) |
425 | { |
426 | if(pf) |
427 | return fputc(c,pf); |
428 | else |
429 | return -1; |
430 | } |
431 | |
432 | int |
433 | nw_fputs(const char *s, FILE *pf) |
434 | { |
435 | if(pf) |
436 | return fputs(s, pf); |
437 | else |
438 | return -1; |
439 | } |
440 | |
441 | size_t |
442 | nw_fread(void *buf, size_t size, size_t count, FILE *fp) |
443 | { |
444 | if(fp) |
445 | return fread(buf, size, count, fp); |
446 | else |
447 | return -1; |
448 | } |
449 | |
450 | FILE * |
451 | nw_freopen(const char *path, const char *mode, FILE *stream) |
452 | { |
453 | if(stream) |
454 | return freopen(path, mode, stream); |
455 | else |
456 | return NULL; |
457 | } |
458 | |
459 | int |
460 | nw_fseek(FILE *pf, long offset, int origin) |
461 | { |
462 | if(pf) |
463 | return (fseek(pf, offset, origin)); |
464 | else |
465 | return -1; |
466 | } |
467 | |
468 | int |
469 | nw_fsetpos(FILE *pf, const fpos_t *p) |
470 | { |
471 | if(pf) |
472 | return fsetpos(pf, p); |
473 | else |
474 | return -1; |
475 | } |
476 | |
477 | long |
478 | nw_ftell(FILE *pf) |
479 | { |
480 | if(pf) |
481 | return ftell(pf); |
482 | else |
483 | return -1; |
484 | } |
485 | |
486 | size_t |
487 | nw_fwrite(const void *buf, size_t size, size_t count, FILE *fp) |
488 | { |
489 | if(fp) |
490 | return fwrite(buf, size, count, fp); |
491 | else |
492 | return -1; |
493 | } |
494 | |
495 | long |
496 | nw_get_osfhandle(int fd) |
497 | { |
498 | return 0l; |
499 | } |
500 | |
501 | int |
502 | nw_getc(FILE *pf) |
503 | { |
504 | if(pf) |
505 | return getc(pf); |
506 | else |
507 | return -1; |
508 | } |
509 | |
510 | int |
511 | nw_putc(int c, FILE *pf) |
512 | { |
513 | if(pf) |
514 | return putc(c,pf); |
515 | else |
516 | return -1; |
517 | } |
518 | |
519 | int |
520 | nw_fgetc(FILE *pf) |
521 | { |
522 | if(pf) |
523 | return fgetc(pf); |
524 | else |
525 | return -1; |
526 | } |
527 | |
528 | int |
529 | nw_getpid(void) |
530 | { |
531 | return GetThreadGroupID(); |
532 | } |
533 | |
534 | int |
535 | nw_kill(int pid, int sig) |
536 | { |
537 | return 0; |
538 | } |
539 | |
540 | int |
541 | nw_link(const char *oldname, const char *newname) |
542 | { |
543 | return 0; |
544 | } |
545 | |
546 | long |
547 | nw_lseek(int fd, long offset, int origin) |
548 | { |
549 | return lseek(fd, offset, origin); |
550 | } |
551 | |
552 | int |
553 | nw_chdir(const char *dir) |
554 | { |
555 | return chdir(dir); |
556 | } |
557 | |
558 | int |
559 | nw_rmdir(const char *dir) |
560 | { |
561 | return rmdir(dir); |
562 | } |
563 | |
564 | DIR * |
565 | nw_opendir(char *filename) |
566 | { |
567 | char *buff = NULL; |
568 | int len = 0; |
569 | DIR *ret = NULL; |
570 | |
571 | len = strlen(filename); |
572 | buff = malloc(len + 5); |
573 | if (buff) { |
574 | strcpy(buff, filename); |
575 | if (buff[len-1]=='/' || buff[len-1]=='\\') { |
576 | buff[--len] = 0; |
577 | } |
578 | strcpy(buff+len, "/*.*"); |
579 | ret = opendir(buff); |
580 | free (buff); |
581 | buff = NULL; |
582 | return ret; |
583 | } else { |
584 | return NULL; |
585 | } |
586 | } |
587 | |
588 | int |
589 | nw_open(const char *path, int flag, ...) |
590 | { |
591 | va_list ap; |
592 | int pmode = -1; |
593 | |
594 | va_start(ap, flag); |
595 | pmode = va_arg(ap, int); |
596 | va_end(ap); |
597 | |
011f1a1a |
598 | if (stricmp(path, "/dev/null")==0) |
2ea608c3 |
599 | path = "NWNUL"; |
2986a63f |
600 | |
601 | return open(path, flag, pmode); |
602 | } |
603 | |
604 | int |
605 | nw_open_osfhandle(long handle, int flags) |
606 | { |
607 | return 0; |
608 | } |
609 | |
610 | unsigned long |
611 | nw_os_id(void) |
612 | { |
613 | return 0l; |
614 | } |
615 | |
616 | int nw_Pipe(int* a, int* e) |
617 | { |
618 | int ret = 0; |
619 | |
620 | errno = 0; |
621 | ret = pipe(a); |
622 | if(errno) |
623 | e = &errno; |
624 | |
625 | return ret; |
626 | } |
627 | |
628 | FILE* nw_Popen(char* command, char* mode, int* e) |
629 | { |
630 | int i = -1; |
631 | |
632 | FILE* ret = NULL; |
633 | PTEMPPIPEFILE ptpf = NULL; |
634 | |
635 | // this callback is supposed to call _popen, which spawns an |
636 | // asynchronous command and opens a pipe to it. The returned |
637 | // file handle can be read or written to; if read, it represents |
638 | // stdout of the called process and will return EOF when the |
639 | // called process finishes. If written to, it represents stdin |
640 | // of the called process. Naturally _popen is not available on |
641 | // NetWare so we must do some fancy stuff to simulate it. We will |
642 | // redirect to and from temp files; this has the side effect |
643 | // of having to run the process synchronously rather than |
644 | // asynchronously. This means that you will only be able to do |
645 | // this with CLIB NLMs built to run on the calling thread. |
646 | |
647 | errno = 0; |
648 | |
649 | ptpf1[iPopenCount] = (PTEMPPIPEFILE) malloc(sizeof(TEMPPIPEFILE)); |
650 | if (!ptpf1[iPopenCount]) |
651 | return NULL; |
652 | |
653 | ptpf = ptpf1[iPopenCount]; |
654 | iPopenCount ++; |
655 | if(iPopenCount > MAX_PIPE_RECURSION) |
656 | iPopenCount = MAX_PIPE_RECURSION; // Limit to the max no of pipes to be open recursively. |
657 | |
658 | fnTempPipeFile(ptpf); |
659 | ret = fnPipeFileOpen((PTEMPPIPEFILE) ptpf, (char *) command, (char *) mode); |
660 | if (ret) |
661 | File1[iPopenCount-1] = ret; // Store the obtained Pipe file handle. |
662 | else |
663 | { // Pipe file not obtained. So free the allocated memory. |
664 | if(ptpf1[iPopenCount-1]) |
665 | { |
666 | free(ptpf1[iPopenCount-1]); |
667 | ptpf1[iPopenCount-1] = NULL; |
668 | ptpf = NULL; |
669 | iPopenCount --; |
670 | } |
671 | } |
672 | |
673 | if (errno) |
674 | e = &errno; |
675 | |
676 | return ret; |
677 | } |
678 | |
679 | int nw_Pclose(FILE* file, int* e) |
680 | { |
681 | int i=0, j=0; |
682 | |
683 | errno = 0; |
684 | |
685 | if(file) |
686 | { |
687 | if(iPopenCount > 0) |
688 | { |
689 | for (i=0; i<iPopenCount; i++) |
690 | { |
691 | if(File1[i] == file) |
692 | { |
693 | // Delete the memory allocated corresponding to the file handle passed-in and |
694 | // also close the file corresponding to the file handle passed-in! |
695 | if(ptpf1[i]) |
696 | { |
697 | fnPipeFileClose(ptpf1[i]); |
698 | |
699 | free(ptpf1[i]); |
700 | ptpf1[i] = NULL; |
701 | } |
702 | |
703 | fclose(File1[i]); |
704 | File1[i] = NULL; |
705 | |
706 | break; |
707 | } |
708 | } |
709 | |
710 | // Rearrange the file pointer array |
711 | for(j=i; j<(iPopenCount-1); j++) |
712 | { |
713 | File1[j] = File1[j+1]; |
714 | ptpf1[j] = ptpf1[j+1]; |
715 | } |
716 | iPopenCount--; |
717 | } |
718 | } |
719 | else |
720 | return -1; |
721 | |
722 | if (errno) |
723 | e = &errno; |
724 | |
725 | return 0; |
726 | } |
727 | |
728 | |
729 | int |
730 | nw_vprintf(const char *format, va_list args) |
731 | { |
732 | return (vprintf(format, args)); |
733 | } |
734 | |
735 | int |
736 | nw_printf(const char *format, ...) |
737 | { |
738 | |
739 | va_list marker; |
740 | va_start(marker, format); /* Initialize variable arguments. */ |
741 | |
742 | return (vprintf(format, marker)); |
743 | } |
744 | |
745 | int |
746 | nw_read(int fd, void *buf, unsigned int cnt) |
747 | { |
748 | return read(fd, buf, cnt); |
749 | } |
750 | |
751 | struct direct * |
752 | nw_readdir(DIR *dirp) |
753 | { |
754 | DIR* ret=NULL; |
755 | |
756 | ret = readdir(dirp); |
757 | if(ret) |
758 | return((struct direct *)ret); |
759 | return NULL; |
760 | } |
761 | |
762 | int |
763 | nw_rename(const char *oname, const char *newname) |
764 | { |
765 | return(rename(oname,newname)); |
766 | } |
767 | |
768 | void |
769 | nw_rewinddir(DIR *dirp) |
770 | { |
acfe0abc |
771 | dTHX; |
4d76e4b4 |
772 | Perl_croak(aTHX_ "The rewinddir() function is not implemented on NetWare\n"); |
2986a63f |
773 | } |
774 | |
775 | void |
776 | nw_rewind(FILE *pf) |
777 | { |
778 | if(pf) |
779 | rewind(pf); |
780 | } |
781 | |
782 | void |
783 | nw_seekdir(DIR *dirp, long loc) |
784 | { |
acfe0abc |
785 | dTHX; |
4d76e4b4 |
786 | Perl_croak(aTHX_ "The seekdir() function is not implemented on NetWare\n"); |
2986a63f |
787 | } |
788 | |
789 | int * |
790 | nw_errno(void) |
791 | { |
792 | return (&errno); |
793 | } |
794 | |
795 | char *** |
796 | nw_environ(void) |
797 | { |
798 | return ((char ***)nw_getenviron()); |
799 | } |
800 | |
801 | char * |
802 | nw_strerror(int e) |
803 | { |
804 | return (strerror(e)); |
805 | } |
806 | |
807 | int |
808 | nw_isatty(int fd) |
809 | { |
810 | return(isatty(fd)); |
811 | } |
812 | |
813 | char * |
814 | nw_mktemp(char *Template) |
815 | { |
816 | return (fnMy_MkTemp(Template)); |
817 | } |
818 | |
819 | int |
820 | nw_chsize(int handle, long size) |
821 | { |
822 | return(chsize(handle,size)); |
823 | } |
824 | |
825 | #ifdef HAVE_INTERP_INTERN |
826 | void |
827 | sys_intern_init(pTHX) |
828 | { |
829 | |
830 | } |
831 | |
832 | void |
833 | sys_intern_clear(pTHX) |
834 | { |
835 | |
836 | } |
837 | |
838 | void |
839 | sys_intern_dup(pTHX_ struct interp_intern *src, struct interp_intern *dst) |
840 | { |
841 | |
842 | } |
843 | #endif /* HAVE_INTERP_INTERN */ |
844 | |
845 | void |
846 | Perl_init_os_extras(void) |
847 | { |
848 | |
849 | } |
850 | |
851 | void |
852 | Perl_nw5_init(int *argcp, char ***argvp) |
853 | { |
854 | MALLOC_INIT; |
855 | } |
856 | |
afbec6b0 |
857 | #ifdef USE_ITHREADS |
858 | PerlInterpreter * |
859 | perl_clone_host(PerlInterpreter* proto_perl, UV flags) |
860 | { |
861 | // Perl Clone is not implemented on NetWare. |
862 | return NULL; |
863 | } |
864 | #endif |
865 | |
2986a63f |
866 | // Some more functions: |
867 | |
868 | char * |
869 | nw_get_sitelib(const char *pl) |
870 | { |
871 | return (NULL); |
872 | } |
873 | |
874 | int |
875 | execv(char *cmdname, char **argv) |
876 | { |
877 | // This feature needs to be implemented. |
878 | // _asm is commented out since it goes into the internal debugger. |
879 | // _asm {int 3}; |
880 | return(0); |
881 | } |
882 | |
883 | int |
884 | execvp(char *cmdname, char **argv) |
885 | { |
886 | // This feature needs to be implemented. |
887 | // _asm is commented out since it goes into the internal debugger. |
888 | // _asm {int 3}; |
889 | return(0); |
890 | } |
891 | |
892 | int |
893 | do_aspawn(void *vreally, void **vmark, void **vsp) |
894 | { |
895 | // This feature needs to be implemented. |
896 | // _asm is commented out since it goes into the internal debugger. |
897 | // _asm {int 3}; |
fa03377f |
898 | //// return(0); |
899 | |
900 | |
901 | // This below code is required for system() call. |
902 | // Otherwise system() does not work on NetWare. |
903 | // Ananth, 3 Sept 2001 |
904 | |
905 | dTHX; |
906 | SV *really = (SV*)vreally; |
907 | SV **mark = (SV**)vmark; |
908 | SV **sp = (SV**)vsp; |
909 | char **argv; |
910 | char *str; |
911 | int status; |
912 | int flag = P_WAIT; |
913 | int index = 0; |
914 | |
915 | |
916 | if (sp <= mark) |
917 | return -1; |
918 | |
919 | nw_perlshell_items = 0; // No Shell |
920 | New(1306, argv, (sp - mark) + nw_perlshell_items + 3, char*); |
921 | |
922 | if (SvNIOKp(*(mark+1)) && !SvPOKp(*(mark+1))) { |
923 | ++mark; |
924 | flag = SvIVx(*mark); |
925 | } |
926 | |
927 | while (++mark <= sp) { |
928 | if (*mark && (str = (char *)SvPV_nolen(*mark))) |
929 | { |
930 | argv[index] = str; |
931 | index++; |
932 | } |
933 | else |
934 | { |
935 | argv[index] = ""; |
936 | // argv[index] = '\0'; |
937 | index++; |
938 | } |
939 | } |
940 | argv[index] = '\0'; |
941 | index++; |
942 | |
943 | status = nw_spawnvp(flag, |
944 | (char*)(really ? SvPV_nolen(really) : argv[0]), |
945 | (char**)argv); |
946 | |
947 | |
948 | if (flag != P_NOWAIT) { |
949 | if (status < 0) { |
950 | dTHR; |
951 | if (ckWARN(WARN_EXEC)) |
f98bc0c6 |
952 | Perl_warner(aTHX_ packWARN(WARN_EXEC), "Can't spawn \"%s\": %s", argv[0], strerror(errno)); |
fa03377f |
953 | status = 255 * 256; |
954 | } |
955 | else |
956 | status *= 256; |
957 | PL_statusvalue = status; |
958 | } |
959 | |
960 | Safefree(argv); |
961 | return (status); |
2986a63f |
962 | } |
963 | |
964 | int |
965 | do_spawn2(char *cmd, int exectype) |
966 | { |
967 | // This feature needs to be implemented. |
968 | // _asm is commented out since it goes into the internal debugger. |
969 | // _asm {int 3}; |
970 | return(0); |
971 | } |
972 | |
973 | int |
974 | do_spawn(char *cmd) |
975 | { |
976 | return do_spawn2(cmd, 2); |
977 | } |
978 | |
979 | int |
980 | fork(void) |
981 | { |
982 | return 0; |
983 | } |
984 | |
011f1a1a |
985 | |
986 | // added to remove undefied symbol error in CodeWarrior compilation |
987 | int |
988 | Perl_Ireentrant_buffer_ptr(aTHX) |
989 | { |
990 | return 0; |
991 | } |