diff options
author | Jarkko Hietaniemi <jhi@iki.fi> | 2001-06-16 19:46:38 +0000 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2001-06-16 19:46:38 +0000 |
commit | 2986a63f7e513cf37f46db9f211b77071260031f (patch) | |
tree | 9a6e62602396938ea5a612420f53ebf267e8d941 /NetWare/nw5.c | |
parent | 87b11a197a59fac210fc9265bde0ef1ffe36de89 (diff) | |
download | perl-2986a63f7e513cf37f46db9f211b77071260031f.tar.gz |
NetWare port from Guruprasad S <SGURUPRASAD@novell.com>.
p4raw-id: //depot/perl@10643
Diffstat (limited to 'NetWare/nw5.c')
-rw-r--r-- | NetWare/nw5.c | 896 |
1 files changed, 896 insertions, 0 deletions
diff --git a/NetWare/nw5.c b/NetWare/nw5.c new file mode 100644 index 0000000000..e32fdb6b2f --- /dev/null +++ b/NetWare/nw5.c @@ -0,0 +1,896 @@ + +/* + * Copyright © 2001 Novell, Inc. All Rights Reserved. + * + * You may distribute under the terms of either the GNU General Public + * License or the Artistic License, as specified in the README file. + * + */ + +/* + * FILENAME : nw5.c + * DESCRIPTION : Definitions for the redefined functions for NetWare. + * Author : SGP, HYAK + * Date : January 2001. + * + */ + + + +#include <perl.h> // For dTHXo, etc. +#include "nwpipe.h" + + +// This was added since the compile failed saying "undefined P_WAIT" +// when USE_ITHREADS was commented in the makefile +#ifndef P_WAIT +#define P_WAIT 0 +#endif + +#ifndef P_NOWAIT +#define P_NOWAIT 1 +#endif + +// The array is used to store pointer to the memory allocated to the TempPipeFile structure everytime +// a call to the function, nw_Popen. If a simple variable is used, everytime the memory is allocated before +// the previously allocated memory is freed, the pointer will get overwritten and the previous memory allocations +// are lost! Only the most recent one will get freed when calls are made to nw_Pclose. +// By using the array and the iPopenCount to index the array, all memory are freed! + +// The size of the array indicates the limit on the no of times the nw_Popen function can be called (and +// memory allocted) from within a script through backtick operators! +// This is arbitrarily set to MAX_PIPE_RECURSION=256 which indicates there can be 256 nested backtick operators possible! +PTEMPPIPEFILE ptpf1[MAX_PIPE_RECURSION] = {'\0'}; +int iPopenCount = 0; +FILE* File1[MAX_PIPE_RECURSION] = {'\0'}; + + +/** +General: + +In this code, wherever there is a FILE *, the error condition is checked; and only if the FILE * is TRUE, +then the corresponding operation is done. Otherwise the error value is returned. +This is done because the file operations like "open" in the Perl code returns the FILE *, +returning a valid value if the file is found or NULL when the particular file is not found. +Now, if the return value is NULL, then an operation say "fgets", "fopen" etc. using this this NULL value +for FILE * will abend the server. If the check is made then an operation on a non existing file +does not abend the server. +**/ + +void +nw_abort(void) +{ + abort(); // Terminate the NLM application abnormally. + return; +} + +int +nw_access(const char *path, int mode) +{ + return access(path, mode); +} + +int +nw_chmod(const char *path, int mode) +{ + return chmod(path, mode); +} + +void +nw_clearerr(FILE *pf) +{ + if(pf) + clearerr(pf); +} + +int +nw_close(int fd) +{ + return close(fd); +} + +nw_closedir(DIR *dirp) +{ + return (closedir(dirp)); +} + +void +nw_setbuf(FILE *pf, char *buf) +{ + if(pf) + setbuf(pf, buf); +} + +int +nw_setmode(FILE *fp, int mode) +{ + int *dummy = 0; + return(fnFpSetMode(fp, mode, dummy)); +} + +int +nw_setvbuf(FILE *pf, char *buf, int type, size_t size) +{ + if(pf) + return setvbuf(pf, buf, type, size); + else + return -1; +} + + +unsigned int +nw_sleep(unsigned int t) +{ + delay(t*1000); // Put the thread to sleep for 't' seconds. Initially 't' is passed in milliseconds. + return 0; +} + +int +nw_spawnvp(int mode, char *cmdname, char **argv) +{ + // There is no pass-around environment on NetWare so we throw that + // argument away for now. + + // The function "spawnvp" does not work in all situations. Loading + // edit.nlm seems to work, for example, but the name of the file + // to edit does not appear to get passed correctly. Another problem + // is that on Netware, P_WAIT does not really work reliably. It only + // works with NLMs built to use CLIB (according to Nile Thayne). + // NLMs such as EDIT that are written directly to the system have no + // way of running synchronously from another process. The whole + // architecture on NetWare seems pretty busted, so we just support it + // as best we can. + // + // The spawnvp function only launches NLMs, it will not execute a command; + // the NetWare "system" function is used for that purpose. Unfortunately, "system" + // always returns success whether the command is successful or not or even + // if the command was not found! To avoid ambiguity--you can have both an + // NLM named "perl" and a system command named "perl"--we need to + // force perl scripts to carry the word "load" when loading an NLM. This + // might be clearer anyway. + + int ret = 0; + int argc = 0; + + + if (stricmp(cmdname, LOAD_COMMAND) == 0) + { + if (argv[1] != NULL) + ret = spawnvp(mode, argv[1], &argv[1]); + } + else + { + int i=0; + while (argv[i] != '\0') + i++; + argc = i; + + fnSystemCommand(argv, argc); + } + + return ret; +} + +int +nw_execv(char *cmdname, char **argv) +{ + return spawnvp(P_WAIT, cmdname, (char **)argv); +} + + +int +nw_execvp(char *cmdname, char **argv) +{ + return nw_spawnvp(P_WAIT, cmdname, (char **)argv); +} + +int +nw_stat(const char *path, struct stat *sbuf) +{ + return (stat(path, sbuf)); +} + +FILE * +nw_stderr(void) +{ + return (stderr); +} + +FILE * +nw_stdin(void) +{ + return (stdin); +} + +FILE * +nw_stdout() +{ + return (stdout); +} + +long +nw_telldir(DIR *dirp) +{ + dTHXo; + Perl_croak(aTHX_ "telldir function is not implemented"); + return 0l; +} + +int +nw_times(struct tms *timebuf) +{ + clock_t now = clock(); + + timebuf->tms_utime = now; + timebuf->tms_stime = 0; + timebuf->tms_cutime = 0; + timebuf->tms_cstime = 0; + + return 0; +} + +FILE* +nw_tmpfile(void) +{ + return tmpfile(); +} + +int +nw_uname(struct utsname *name) +{ + return(uname(name)); +} + +int +nw_ungetc(int c, FILE *pf) +{ + if(pf) + return ungetc(c, pf); + else + return -1; +} + +int +nw_unlink(const char *filename) +{ + return(unlink(filename)); +} + +int +nw_utime(const char *filename, struct utimbuf *times) +{ + return(utime(filename, times)); +} + +int +nw_vfprintf(FILE *fp, const char *format, va_list args) +{ + if(fp) + return (vfprintf(fp, format, args)); + else + return -1; +} + +int +nw_wait(int *status) +{ + return 0; +} + +int +nw_waitpid(int pid, int *status, int flags) +{ + return 0; +} + +int +nw_write(int fd, const void *buf, unsigned int cnt) +{ + return write(fd, buf, cnt); +} + +char * +nw_crypt(const char *txt, const char *salt) +{ + dTHXo; + +#ifdef HAVE_DES_FCRYPT + dTHR; + return des_fcrypt(txt, salt, w32_crypt_buffer); +#else + Perl_croak(aTHX_ "The crypt() function is unimplemented due to excessive paranoia."); + return Nullch; +#endif +} + +int +nw_dup(int fd) +{ + return dup(fd); +} + +int +nw_dup2(int fd1,int fd2) +{ + return dup2(fd1,fd2); +} + +void* +nw_dynaload(const char* filename) +{ + return NULL; +} + +int +nw_fclose(FILE *pf) +{ + if(pf) + return (fclose(pf)); + else + return -1; +} + +FILE * +nw_fdopen(int handle, const char *mode) +{ + return(fdopen(handle, mode)); +} + +int +nw_feof(FILE *fp) +{ + if(fp) + return (feof(fp)); + else + return -1; +} + +int +nw_ferror(FILE *fp) +{ + if(fp) + return (ferror(fp)); + else + return -1; +} + + +int +nw_fflush(FILE *pf) +{ + if(pf) + return fflush(pf); + else + return -1; +} + +int +nw_fgetpos(FILE *pf, fpos_t *p) +{ + if(pf) + return fgetpos(pf, p); + else + return -1; +} + +char* +nw_fgets(char *s, int n, FILE *pf) +{ + if(pf) + return(fgets(s, n, pf)); + else + return NULL; +} + +int +nw_fileno(FILE *pf) +{ + if(pf) + return fileno(pf); + else + return -1; +} + +int +nw_flock(int fd, int oper) +{ + return 0; +} + + +FILE * +nw_fopen(const char *filename, const char *mode) +{ + return (fopen(filename, mode)); +} + +int +nw_fputc(int c, FILE *pf) +{ + if(pf) + return fputc(c,pf); + else + return -1; +} + +int +nw_fputs(const char *s, FILE *pf) +{ + if(pf) + return fputs(s, pf); + else + return -1; +} + +size_t +nw_fread(void *buf, size_t size, size_t count, FILE *fp) +{ + if(fp) + return fread(buf, size, count, fp); + else + return -1; +} + +FILE * +nw_freopen(const char *path, const char *mode, FILE *stream) +{ + if(stream) + return freopen(path, mode, stream); + else + return NULL; +} + +int +nw_fseek(FILE *pf, long offset, int origin) +{ + if(pf) + return (fseek(pf, offset, origin)); + else + return -1; +} + +int +nw_fsetpos(FILE *pf, const fpos_t *p) +{ + if(pf) + return fsetpos(pf, p); + else + return -1; +} + +long +nw_ftell(FILE *pf) +{ + if(pf) + return ftell(pf); + else + return -1; +} + +size_t +nw_fwrite(const void *buf, size_t size, size_t count, FILE *fp) +{ + if(fp) + return fwrite(buf, size, count, fp); + else + return -1; +} + +long +nw_get_osfhandle(int fd) +{ + return 0l; +} + +int +nw_getc(FILE *pf) +{ + if(pf) + return getc(pf); + else + return -1; +} + +int +nw_putc(int c, FILE *pf) +{ + if(pf) + return putc(c,pf); + else + return -1; +} + +int +nw_fgetc(FILE *pf) +{ + if(pf) + return fgetc(pf); + else + return -1; +} + +int +nw_getpid(void) +{ + return GetThreadGroupID(); +} + +int +nw_kill(int pid, int sig) +{ + return 0; +} + +int +nw_link(const char *oldname, const char *newname) +{ + return 0; +} + +long +nw_lseek(int fd, long offset, int origin) +{ + return lseek(fd, offset, origin); +} + +int +nw_chdir(const char *dir) +{ + return chdir(dir); +} + +int +nw_rmdir(const char *dir) +{ + return rmdir(dir); +} + +DIR * +nw_opendir(char *filename) +{ + char *buff = NULL; + int len = 0; + DIR *ret = NULL; + + len = strlen(filename); + buff = malloc(len + 5); + if (buff) { + strcpy(buff, filename); + if (buff[len-1]=='/' || buff[len-1]=='\\') { + buff[--len] = 0; + } + strcpy(buff+len, "/*.*"); + ret = opendir(buff); + free (buff); + buff = NULL; + return ret; + } else { + return NULL; + } +} + +int +nw_open(const char *path, int flag, ...) +{ + va_list ap; + int pmode = -1; + + va_start(ap, flag); + pmode = va_arg(ap, int); + va_end(ap); + + if (stricmp(path, "/dev/null")==0) + path = "NUL"; + + return open(path, flag, pmode); +} + +int +nw_open_osfhandle(long handle, int flags) +{ + return 0; +} + +unsigned long +nw_os_id(void) +{ + return 0l; +} + +int nw_Pipe(int* a, int* e) +{ + int ret = 0; + + errno = 0; + ret = pipe(a); + if(errno) + e = &errno; + + return ret; +} + +FILE* nw_Popen(char* command, char* mode, int* e) +{ + int i = -1; + + FILE* ret = NULL; + PTEMPPIPEFILE ptpf = NULL; + + // this callback is supposed to call _popen, which spawns an + // asynchronous command and opens a pipe to it. The returned + // file handle can be read or written to; if read, it represents + // stdout of the called process and will return EOF when the + // called process finishes. If written to, it represents stdin + // of the called process. Naturally _popen is not available on + // NetWare so we must do some fancy stuff to simulate it. We will + // redirect to and from temp files; this has the side effect + // of having to run the process synchronously rather than + // asynchronously. This means that you will only be able to do + // this with CLIB NLMs built to run on the calling thread. + + errno = 0; + + ptpf1[iPopenCount] = (PTEMPPIPEFILE) malloc(sizeof(TEMPPIPEFILE)); + if (!ptpf1[iPopenCount]) + return NULL; + + ptpf = ptpf1[iPopenCount]; + iPopenCount ++; + if(iPopenCount > MAX_PIPE_RECURSION) + iPopenCount = MAX_PIPE_RECURSION; // Limit to the max no of pipes to be open recursively. + + fnTempPipeFile(ptpf); + ret = fnPipeFileOpen((PTEMPPIPEFILE) ptpf, (char *) command, (char *) mode); + if (ret) + File1[iPopenCount-1] = ret; // Store the obtained Pipe file handle. + else + { // Pipe file not obtained. So free the allocated memory. + if(ptpf1[iPopenCount-1]) + { + free(ptpf1[iPopenCount-1]); + ptpf1[iPopenCount-1] = NULL; + ptpf = NULL; + iPopenCount --; + } + } + + if (errno) + e = &errno; + + return ret; +} + +int nw_Pclose(FILE* file, int* e) +{ + int i=0, j=0; + + errno = 0; + + if(file) + { + if(iPopenCount > 0) + { + for (i=0; i<iPopenCount; i++) + { + if(File1[i] == file) + { + // Delete the memory allocated corresponding to the file handle passed-in and + // also close the file corresponding to the file handle passed-in! + if(ptpf1[i]) + { + fnPipeFileClose(ptpf1[i]); + + free(ptpf1[i]); + ptpf1[i] = NULL; + } + + fclose(File1[i]); + File1[i] = NULL; + + break; + } + } + + // Rearrange the file pointer array + for(j=i; j<(iPopenCount-1); j++) + { + File1[j] = File1[j+1]; + ptpf1[j] = ptpf1[j+1]; + } + iPopenCount--; + } + } + else + return -1; + + if (errno) + e = &errno; + + return 0; +} + + +int +nw_vprintf(const char *format, va_list args) +{ + return (vprintf(format, args)); +} + +int +nw_printf(const char *format, ...) +{ + + va_list marker; + va_start(marker, format); /* Initialize variable arguments. */ + + return (vprintf(format, marker)); +} + +int +nw_read(int fd, void *buf, unsigned int cnt) +{ + return read(fd, buf, cnt); +} + +struct direct * +nw_readdir(DIR *dirp) +{ + DIR* ret=NULL; + + ret = readdir(dirp); + if(ret) + return((struct direct *)ret); + return NULL; +} + +int +nw_rename(const char *oname, const char *newname) +{ + return(rename(oname,newname)); +} + +void +nw_rewinddir(DIR *dirp) +{ + dTHXo; + Perl_croak(aTHX_ "rewinddir function is not implemented"); +} + +void +nw_rewind(FILE *pf) +{ + if(pf) + rewind(pf); +} + +void +nw_seekdir(DIR *dirp, long loc) +{ + dTHXo; + Perl_croak(aTHX_ "seekdir function is not implemented"); +} + +int * +nw_errno(void) +{ + return (&errno); +} + +char *** +nw_environ(void) +{ + return ((char ***)nw_getenviron()); +} + +char * +nw_strerror(int e) +{ + return (strerror(e)); +} + +int +nw_isatty(int fd) +{ + return(isatty(fd)); +} + +char * +nw_mktemp(char *Template) +{ + return (fnMy_MkTemp(Template)); +} + +int +nw_chsize(int handle, long size) +{ + return(chsize(handle,size)); +} + +#ifdef HAVE_INTERP_INTERN +void +sys_intern_init(pTHX) +{ + +} + +void +sys_intern_clear(pTHX) +{ + +} + +void +sys_intern_dup(pTHX_ struct interp_intern *src, struct interp_intern *dst) +{ + +} +#endif /* HAVE_INTERP_INTERN */ + +void +Perl_init_os_extras(void) +{ + +} + +void +Perl_nw5_init(int *argcp, char ***argvp) +{ + MALLOC_INIT; +} + +// Some more functions: + +char * +nw_get_sitelib(const char *pl) +{ + return (NULL); +} + +int +execv(char *cmdname, char **argv) +{ + // This feature needs to be implemented. + // _asm is commented out since it goes into the internal debugger. +// _asm {int 3}; + return(0); +} + +int +execvp(char *cmdname, char **argv) +{ + // This feature needs to be implemented. + // _asm is commented out since it goes into the internal debugger. +// _asm {int 3}; + return(0); +} + +int +do_aspawn(void *vreally, void **vmark, void **vsp) +{ + // This feature needs to be implemented. + // _asm is commented out since it goes into the internal debugger. +// _asm {int 3}; + return(0); +} + +int +do_spawn2(char *cmd, int exectype) +{ + // This feature needs to be implemented. + // _asm is commented out since it goes into the internal debugger. +// _asm {int 3}; + return(0); +} + +int +do_spawn(char *cmd) +{ + return do_spawn2(cmd, 2); +} + +int +fork(void) +{ + return 0; +} + |