diff options
author | Kim Kibum <kb0929.kim@samsung.com> | 2012-05-21 17:42:43 +0900 |
---|---|---|
committer | Kim Kibum <kb0929.kim@samsung.com> | 2012-05-21 17:42:43 +0900 |
commit | 4a2c24a45b7af1aa715eae442c7ef3d91e7dde6d (patch) | |
tree | 5431ff1d419d4ee35f8bd3cb3ebd5e334c2a737e /pc/gawkmisc.pc | |
parent | c22a3ed09b982b93feb23655eba7b55fa27885cb (diff) | |
download | gawk-4a2c24a45b7af1aa715eae442c7ef3d91e7dde6d.tar.gz gawk-4a2c24a45b7af1aa715eae442c7ef3d91e7dde6d.tar.bz2 gawk-4a2c24a45b7af1aa715eae442c7ef3d91e7dde6d.zip |
Upload Tizen:Base source
Diffstat (limited to 'pc/gawkmisc.pc')
-rw-r--r-- | pc/gawkmisc.pc | 455 |
1 files changed, 455 insertions, 0 deletions
diff --git a/pc/gawkmisc.pc b/pc/gawkmisc.pc new file mode 100644 index 0000000..5164edb --- /dev/null +++ b/pc/gawkmisc.pc @@ -0,0 +1,455 @@ +/* + * gawkmisc.c --- miscellaneous gawk routines that are OS specific. + */ + +/* + * Copyright (C) 1986, 1988, 1989, 1991 - 2003 the Free Software Foundation, Inc. + * + * This file is part of GAWK, the GNU implementation of the + * AWK Progamming Language. + * + * GAWK is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GAWK is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +char quote = '\''; +char envsep = ';'; + +# ifdef DEFPATH +char *defpath = DEFPATH; +# else +char *defpath = ".;c:\\lib\\awk;c:\\gnu\\lib\\awk"; +# endif + +#ifdef __EMX__ +#include<io.h> + +static int _os2_is_abs_path(const char *dirname); +static char* _os2_unixroot(const char *path); +static const char* _os2_unixroot_path(const char *path); +#endif + +/* gawk_name --- pull out the "gawk" part from how the OS called us */ + +char * +gawk_name(filespec) +const char *filespec; +{ + char *p, *q; + + p = (char *) filespec; /* Sloppy... */ + + /* OS/2 allows / for directory separator too */ + if ((q = strrchr(p, '\\')) != NULL) + p = q + 1; + if ((q = strrchr(p, '/')) != NULL + && (p == NULL || q > p)) /* support mixed d:\foo/bar\gawk.exe */ + p = q + 1; + if ((q = strchr(p, '.')) != NULL) + *q = '\0'; + return strlwr(p); +} + + +/* + * memcpy_long() & memset_ulong() are 32-bit replacements for MSC which + * has a 16-bit size_t. + */ +char * +memcpy_ulong (dest, src, l) +register char *dest; +register const char *src; +register unsigned long l; +{ + register char *ret = dest; + + while (l--) + *dest++ = *src++; + + return ret; +} + + +void * +memset_ulong(dest, val, l) +void *dest; +register int val; +register unsigned long l; +{ + register char *ret = dest; + register char *d = dest; + + while (l--) + *d++ = val; + + return ((void *) ret); +} + + +/* os_arg_fixup --- fixup the command line */ + +void +os_arg_fixup(argcp, argvp) +int *argcp; +char ***argvp; +{ +#ifdef __EMX__ +# ifdef initialize_main + initialize_main(argcp, argvp); +# else + _wildcard(argcp, argvp); + _response(argcp, argvp); +# endif + + setvbuf(stdout, NULL, _IOLBF, BUFSIZ); + defpath = (char*) _os2_unixroot_path(defpath); +#endif /* __EMX__ */ + return; +} + +/* os_devopen --- open special per-OS devices */ + +int +os_devopen(name, flag) +const char *name; +int flag; +{ +#ifdef __EMX__ + /* do not use open(name, flag) here !!! */ + return -1; +#else + if (strcmp(name, "/dev/null") == 0) + return open("NUL", flag); + /* FIXME: */ + /* else if (strcmp(name, "/dev/tty") == 0) + * return open("???", flag); + */ + return -1; +#endif +} + +/* optimal_bufsize --- determine optimal buffer size */ + +size_t +optimal_bufsize(fd, stb) +int fd; +struct stat *stb; +{ + /* force all members to zero in case OS doesn't use all of them. */ + memset(stb, '\0', sizeof(struct stat)); + + /* + * DOS doesn't have the file system block size in the + * stat structure. So we have to make some sort of reasonable + * guess. We use stdio's BUFSIZ, since that is what it was + * meant for in the first place. + */ +#define DEFBLKSIZE BUFSIZ + + if (fstat(fd, stb) == -1) + fatal("can't stat fd %d (%s)", fd, strerror(errno)); + if (S_ISREG(stb->st_mode) + && 0 < stb->st_size && stb->st_size < DEFBLKSIZE) /* small file */ + return stb->st_size; + return DEFBLKSIZE; +} + +/* ispath --- return true if path has directory components */ + +int +ispath(file) +const char *file; +{ +#ifdef __EMX__ + return (strpbrk(file, "/\\") != NULL || + (toupper(file[0]) >= 'A' && toupper(file[0]) <= 'Z' && file[1] == ':')); +#else + for (; *file; file++) { + switch (*file) { + case '/': + case '\\': + case ':': + return 1; + } + } + return 0; +#endif +} + +/* isdirpunct --- return true if char is a directory separator */ + +int +isdirpunct(c) +int c; +{ + return (strchr(":\\/", c) != NULL); +} + +/* os_close_on_exec --- set close on exec flag, print warning if fails */ + +void +os_close_on_exec(fd, name, what, dir) +int fd; +const char *name, *what, *dir; +{ +#if ! defined(_MSC_VER) && ! defined(__MINGW32__) +# if (defined(__DJGPP__) && (__DJGPP__ > 2 || __DJGPP_MINOR__ >= 4)) || defined __EMX__ + if (fd <= 2) /* sanity */ + return; + + if (fcntl(fd, F_SETFD, 1) < 0) + warning("%s %s `%s': could not set close-on-exec: %s", + what, dir, name, strerror(errno)); +# endif +#endif +} + +/* os_isdir --- is this an fd on a directory? */ + +#if ! defined(S_ISDIR) && defined(S_IFDIR) +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#endif + +int +os_isdir(fd) +int fd; +{ + struct stat sbuf; + + return (fstat(fd, &sbuf) == 0 && S_ISDIR(sbuf.st_mode)); +} + +/* os_is_setuid --- true if running setuid root */ + +int +os_is_setuid() +{ +#ifdef __EMX__ + long uid, euid; + + uid = getuid(); + euid = geteuid(); + + return (euid == 0 && euid != uid); +#else + return 0; +#endif +} + +/* os_setbinmode --- set binary mode on file */ + +#ifdef __DJGPP__ +#include <sys/exceptn.h> +#endif +static int orig_tty_mode = -1; + +int +os_setbinmode(fd, mode) +int fd, mode; +{ + int prev_mode = setmode(fd, mode); + +#ifdef __DJGPP__ + if ((mode & O_BINARY) != 0) + __djgpp_set_ctrl_c(1); /* allow to interrupt with Ctrl-C */ +#endif + /* Save the original tty mode as we found it. */ + if (orig_tty_mode == -1 && fd >= 0 && fd <= 2) + orig_tty_mode = prev_mode; + return prev_mode; +} + +/* os_restore_mode --- restore the original mode of the console device */ + +void +os_restore_mode (fd) +int fd; +{ + if (orig_tty_mode != -1) { + setmode(fd, orig_tty_mode); + } +} + + +#ifdef __EMX__ +# ifndef PATH_SEPARATOR +# define PATH_SEPARATOR ';' +# endif + +/* result is 0 if dirname is no absolute path, 1 otherwise */ + +static int +_os2_is_abs_path(const char *dirname) +{ + int result = 0; + if (dirname != NULL && dirname[0] != '\0') { + /* if dirname contains a valid drive letter like "c:" */ + if (((dirname[0] >= 'A' && dirname[0] <= 'Z') || (dirname[0] >= 'a' && dirname[0] <= 'z')) + && dirname[1] == ':') dirname += 2; /* remove the drive letter */ + + if (dirname[0] == '/' || dirname[0] == '\\') result = 1; /* asbolute path */ + } + + return result; +} + + +/* path is assumed to be a list of directories separated by PATH_SEPARATOR. + This function determines if the first directory of path is on the + drive specified by the environment variable UNIXROOT. + If it is the case, NULL is returned, otherwise a new directory name + is allocated using the drive letter from UNIXROOT and returned as result. + If the first directory is a relative path NULL is returned, too. + The new directory name is allocated by malloc(). + Example (UNIXROOT is set to "e:"): + "c:/usr/share" -> "e:/usr/share" + "e:/usr/share" -> NULL (already on the $UNIXROOT drive) + "/usr/share" -> "e:/usr/share" + "." -> NULL (not an absolute path) + "usr/share" -> NULL (not an absolute path) + "c:usr/share" -> NULL (not an absolute path) + "c:/usr/share;d:/etc" -> "e:/usr/share" (only the first directory in path is used) */ + +static char* +_os2_unixroot(const char *path) +{ + static const char *unixroot = NULL; + static int unixroot_init = 0; + char *result = NULL; + + if (unixroot_init == 0) { + /* get $UNIXROOT only one time */ + unixroot = getenv("UNIXROOT"); + + /* check whether unixroot is valid (must be "x:") */ + if (unixroot != NULL) { + int drive = toupper(unixroot[0]); + if (drive < 'A' || drive > 'Z' || unixroot[1] != ':' || unixroot[2] != '\0') + unixroot = NULL; /* unixroot not valid */ + } + + unixroot_init = 1; /* initialized */ + } + + /* note: if unixroot != NULL then it contains a valid drive letter */ + if (unixroot != NULL && _os2_is_abs_path(path)) { + /* dirname is an absolute path and unixroot is a drive letter, "c:" for example */ + size_t old_path_len = strlen(path); + + /* end points to the first ';' in path or to NULL */ + const char *end = strchr(path, PATH_SEPARATOR); + + /* dir_len is the length of the first directory in path */ + size_t dir_len = (end) ? end - path : old_path_len; + + if (toupper(unixroot[0]) != toupper(path[0]) || path[1] != ':') { + /* the first directory of path does not start with the string $UNIXROOT */ + if (path[1] == ':') { + /* if there is a drive letter remove it */ + dir_len -= 2; + path += 2; + } + + result = malloc(dir_len + 3); + if (result) { /* do nothing if we are out of memory */ + result[0] = unixroot[0]; + result[1] = unixroot[1]; + memcpy(result + 2, path, dir_len); + result[dir_len + 2] = '\0'; + } + } + } + return result; +} + +/* path is assumed to be a list of directories separated by PATH_SEPARATOR. + Every directory is processed. _os2_unixroot() is used to find out whether + these directories are on the drive specified by the environment variable + UNIXROOT. If this is not the case the same directory on the UNIXROOT drive + is added to the end of path. If path is a valid path this function returns a valid path, too. + Example ($UNIXROOT is set to "e:"): + ".;c:/usr/local;d:/usr/local;d:/etc;e:/etc" + -> ".;c:/usr/local;d:/usr/local;d:/etc;e:/etc;e:/usr/local;e:/usr/local;e:/etc" */ + +static const char* +_os2_unixroot_path(const char *path) +{ + char *result = NULL; + const char *p = path; + unsigned dir_count = 1; + + if (path == NULL || path[0] == '\0') return NULL; /* empty path */ + + /* save number of path components in dir_count */ + while(*p) { + if (*p++ == PATH_SEPARATOR && *p != '\0' && *p != PATH_SEPARATOR) + dir_count += 1; + } + + { + const char *list[dir_count]; /* list of char pointers */ + size_t dir_len[dir_count]; /* the according directory length */ + size_t old_path_len = strlen(path); /* the old path length */ + size_t total_len; + unsigned i = 0; + + if (path[old_path_len - 1] == PATH_SEPARATOR) /* last character is ';' */ + old_path_len--; + + list[0] = p = path; /* first directory */ + + while(*p) { + if (*p++ == PATH_SEPARATOR && *p != '\0' && *p != PATH_SEPARATOR) + list[++i] = p; + } + /* now list[i] contains the ith directory of path (no 0-terminated strings!!!) */ + + /* determine the total length for the new path */ + total_len = old_path_len; + + for(i = 0; i < dir_count; i++) { + list[i] = _os2_unixroot(list[i]); + if (list[i] != NULL) { + dir_len[i] = strlen(list[i]); + total_len += dir_len[i] + 1; /* one character for ';' or '\0' */ + } + else dir_len[i] = 0; + } + /* now list[] contains the according directories on the UNIXROOT drive or NULL + total_len contains the total length for the new path */ + result = malloc(total_len + 1); + + if (result) { + /* copy the old path and the new directories into the new path */ + char *q = result; + memcpy(q, path, old_path_len); + q += old_path_len; + + for(i = 0; i < dir_count; i++) { + if (dir_len[i] != 0) { + *q++ = PATH_SEPARATOR; + memcpy(q, list[i], dir_len[i]); + q += dir_len[i]; + } + } + + *q = '\0'; /* terminating '\0' */ + } + + for(i = 0; i < dir_count; i++) free((void*) list[i]); + } + + return (result) ? (const char*) result : path; +} +#endif /* __EMX__ */ |