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