home *** CD-ROM | disk | FTP | other *** search
- /*
- * This file forms part of "TKERN" - "Troy's Kernel for Windows".
- *
- * Copyright (C) 1994 Troy Rollo <troy@cbme.unsw.EDU.AU>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- /*
- * This module takes care of tkern file operations. Most of these
- * get passed on to tkfmangr so that files can be inherited by
- * child processes in tkern.
- */
-
- #include <windows.h>
- #include <toolhelp.h>
- #include <stdlib.h>
- #include <memory.h>
- #include <string.h>
- #include <alloc.h>
- #include <stdarg.h>
- #include <errno.h>
- #include <ctype.h>
- #include <dir.h>
- #include <sys/tfile.h>
- #include <sys/task.h>
- #include <sys/ioctl.h>
- #include <sys/wait.h>
- #include <sys/tkern.h>
-
- struct tfile _files[TNFILE];
- static HGLOBAL hTFMem = 0;
- struct tfunc *ptf = 0;
-
- static int
- find_location( struct task *pt,
- int *fd,
- int *ifd)
- {
- for (*ifd = 0; *ifd < TNFILE; (*ifd)++)
- {
- if (!_files[*ifd].tf_cnt)
- break;
- }
- if (*ifd == TNFILE)
- {
- pt->nError = EMFILE;
- return -1;
- }
- for (*fd = 0; *fd < UFILE_MAX; (*fd)++)
- {
- if (pt->files[*fd] == -1)
- break;
- }
- if (*fd == UFILE_MAX)
- {
- pt->nError = EMFILE;
- return -1;
- }
- return 0;
- }
-
-
- int far _export
- tkern_open( char const *pchFile,
- int nMode,
- int nAccess)
- {
- int iDevice;
- int id;
- int fd;
- int ifd;
- char const *c;
- struct task *pt;
- BOOL bFile;
-
- pt = GetTaskInfo();
- ptf->iTask = (pt - _tasks);
- if (!strncmp(pchFile, "\\dev\\", 5) ||
- !strncmp(pchFile, "/dev/", 5))
- {
- bFile = FALSE;
- strcpy(ptf->achFile, pchFile + 5);
- iDevice = SendMessage(hwndManager, TKWM_GETDEVNO, 0, (LPARAM) ptf);
- pchFile += 5;
- if ((c = strchr(pchFile, '/')) != 0)
- pchFile = c + 1;
- }
- else
- {
- bFile = TRUE;
- strcpy(ptf->achFile, "file");
- iDevice = SendMessage(hwndManager, TKWM_GETDEVNO, 0, (LPARAM) ptf);
- }
-
- if (find_location(pt, &fd, &ifd) == -1)
- return -1;
-
- ptf->iDevice = iDevice;
- ptf->iTask = (pt - _tasks);
- if (bFile)
- {
- if (isalpha(pchFile[0]) && pchFile[1] == ':')
- {
- if (pchFile[2] == '\\')
- {
- strcpy(ptf->achFile, pchFile);
- }
- else
- {
- strncpy(ptf->achFile, pchFile, 2);
- getcurdir(toupper(pchFile[0]), ptf->achFile + 2);
- if (ptf->achFile[strlen(ptf->achFile) - 1] != '\\')
- strcat(ptf->achFile, "\\");
- strcat(ptf->achFile, pchFile + 2);
- }
- }
- else
- {
- if (pchFile[0] == '\\')
- {
- getcwd(ptf->achFile, _FNLEN);
- ptf->achFile[2] = '\0';
- strcat(ptf->achFile, pchFile);
- }
- else
- {
- getcwd(ptf->achFile, _FNLEN);
- if (ptf->achFile[strlen(ptf->achFile) - 1] != '\\')
- strcat(ptf->achFile, "\\");
- strcat(ptf->achFile, pchFile);
- }
- }
- }
- else
- {
- strcpy(ptf->achFile, pchFile);
- }
- ptf->nMode = nMode;
- ptf->nAccess = nAccess;
- id = SendMessage(hwndManager, TKWM_OPEN, 0, (LPARAM) ptf);
- if (id == -1)
- return -1;
- _files[ifd].tf_cnt = 1;
- _files[ifd].tf_id = id;
- _files[ifd].tf_dev = iDevice;
- pt->files[fd] = ifd;
- return fd;
- }
-
- long far _export
- tkern_seek( int fd,
- long nPosition,
- int nStart)
- {
- struct task *pt;
-
- pt = GetTaskInfo();
- if (fd < 0 || fd >= UFILE_MAX || pt->files[fd] == -1)
- {
- pt->nError = EBADF;
- return -1;
- }
- ptf->iDevice = _files[pt->files[fd]].tf_dev;
- ptf->iTask = (pt - _tasks);
- ptf->nPosition = nPosition;
- ptf->nFrom = nStart;
- return SendMessage(hwndManager, TKWM_SEEK,
- _files[pt->files[fd]].tf_id,
- (LPARAM) ptf);
- }
-
- int far _export
- tkern_read( int fd,
- char *pchBuffer,
- int nBytes)
- {
- struct task *pt;
- LRESULT nRead;
- int nTotal = 0;
- int nNow;
-
- pt = GetTaskInfo();
- if (fd < 0 || fd >= UFILE_MAX || pt->files[fd] == -1)
- {
- pt->nError = EBADF;
- return -1;
- }
- if (nBytes < 0)
- {
- pt->nError = EINVAL;
- return -1;
- }
- if (_files[pt->files[fd]].tf_eof)
- {
- _files[pt->files[fd]].tf_eof = 0;
- return 0;
- }
- while(1)
- {
- /*
- * We set this structure up inside the loop because it is shared among
- * tasks, and if we end up sleeping, another task may overwrite this
- */
- nNow = nBytes;
- if (nNow > _FBUFSZ)
- nNow = _FBUFSZ;
- ptf->iDevice = _files[pt->files[fd]].tf_dev;
- ptf->iTask = (pt - _tasks);
- ptf->nBytes = nNow;
- nRead = SendMessage(hwndManager, TKWM_READ,
- _files[pt->files[fd]].tf_id,
- (LPARAM) ptf);
- if (nRead == -1)
- {
- return -1;
- }
- if (nRead != FR_NOTREADY)
- {
- nTotal += (int) nRead;
- nBytes -= (int) nRead;
- memcpy(pchBuffer, ptf->achBuffer, (int) nRead);
- pchBuffer += (int) nRead;
- if (!nBytes || !nRead)
- {
- if (nTotal && !nRead)
- _files[pt->files[fd]].tf_eof = 1;
- return nTotal;
- }
- }
- else if (nTotal)
- {
- return nTotal;
- }
- else
- {
- GetMessages(pt);
- }
- }
- }
-
- int far _export
- tkern_write( int fd,
- char const *pchBuffer,
- int nBytes)
- {
- struct task *pt;
- int nTotal = 0;
- int nWritten;
- int nNow;
-
- pt = GetTaskInfo();
- if (fd < 0 || fd >= UFILE_MAX || pt->files[fd] == -1)
- {
- pt->nError = EBADF;
- return -1;
- }
- if (nBytes < 0)
- {
- pt->nError = EINVAL;
- return -1;
- }
- while (nBytes)
- {
- nNow = nBytes;
- if (nNow > _FBUFSZ)
- nNow = _FBUFSZ;
- ptf->iDevice = _files[pt->files[fd]].tf_dev;
- ptf->iTask = (pt - _tasks);
- memcpy(ptf->achBuffer, pchBuffer, nNow);
- ptf->nBytes = nNow;
- nWritten = (int) SendMessage(hwndManager, TKWM_WRITE,
- _files[pt->files[fd]].tf_id,
- (LPARAM) ptf);
- if (nWritten == -1)
- return -1;
- if (nWritten != FR_NOTREADY)
- {
- nTotal += (int) nWritten;
- nBytes -= (int) nWritten;
- pchBuffer += (int) nWritten;
- if (!nBytes || !nWritten)
- return nTotal;
- }
- else
- {
- GetMessages(pt);
- }
- }
- return nTotal;
- }
-
- int far _export
- tkern_close( int fd)
- {
- struct task *pt;
- int ifd;
-
- pt = GetTaskInfo();
- if (fd < 0 || fd >= UFILE_MAX || pt->files[fd] == -1)
- {
- pt->nError = EBADF;
- return -1;
- }
- ifd = pt->files[fd];
- pt->files[fd] = -1;
- if (!--_files[ifd].tf_cnt)
- {
- _files[ifd].tf_eof = 0;
- ptf->iTask = (pt - _tasks);
- ptf->iDevice = _files[ifd].tf_dev;
- return SendMessage(hwndManager, TKWM_CLOSE,
- _files[ifd].tf_id,
- (LPARAM) ptf);
- }
- else
- return 0;
- }
-
- void
- internal_close( int fd,
- int iTask)
- {
- int ifd;
-
- ifd = _tasks[iTask].files[fd];
- _tasks[iTask].files[fd] = -1;
- if (!--_files[ifd].tf_cnt)
- {
- ptf->iDevice = _files[ifd].tf_dev;
- ptf->iTask = iTask;
- SendMessage( hwndManager,
- TKWM_CLOSE,
- _files[ifd].tf_id,
- (LPARAM) ptf);
- }
- }
-
- int far _export
- tkern_dup(int fd_in)
- {
- struct task *pt;
- int fd;
-
- pt = GetTaskInfo();
- if (fd_in < 0 || fd_in >= UFILE_MAX || pt->files[fd_in] == -1)
- {
- pt->nError = EBADF;
- return -1;
- }
- for (fd = 0; fd < UFILE_MAX; fd++)
- {
- if (pt->files[fd] == -1)
- {
- pt->files[fd] = pt->files[fd_in];
- _files[pt->files[fd]].tf_cnt++;
- return fd;
- }
- }
- pt->nError = EMFILE;
- return -1;
- }
-
- int far _export
- tkern_dup2( int fd_in,
- int fd)
- {
- struct task *pt;
-
- pt = GetTaskInfo();
- if (fd_in < 0 || fd_in >= UFILE_MAX ||
- fd < 0 || fd >= UFILE_MAX || pt->files[fd_in] == -1)
- {
- pt->nError = EBADF;
- return -1;
- }
- if (pt->files[fd] != -1)
- internal_close(fd, pt - _tasks);
- pt->files[fd] = pt->files[fd_in];
- _files[pt->files[fd]].tf_cnt++;
- return fd;
- }
-
- int far _export
- tkern_pipe(int *pfd)
- {
- if ((pfd[0] = tkern_open("/dev/pipe/input", 0, 0)) == -1)
- return -1;
- if ((pfd[1] = tkern_open("/dev/pipe/output", 0, 0)) == -1)
- {
- tkern_close(pfd[0]);
- return -1;
- }
- return 0;
- }
-
- int far _export
- tkern_isatty(int fd)
- {
- struct task *pt;
-
- pt = GetTaskInfo();
- if (fd < 0 || fd >= UFILE_MAX || pt->files[fd] == -1)
- {
- pt->nError = EBADF;
- return -1;
- }
-
- ptf->iTask = (pt - _tasks);
- ptf->iDevice = _files[pt->files[fd]].tf_dev;
- return SendMessage(hwndManager, TKWM_ISATTY,
- _files[pt->files[fd]].tf_id,
- (LPARAM) ptf);
- }
-
- int far _export
- tkern_ioctl( int fd,
- long nIOCtl,
- char *pchBuffer)
- {
- int nSize = ((nIOCtl & TK_IOCTL_PARM_SIZE) >> 16);
- int iReturn = 0;
- int ifd;
- struct task *pt;
-
- pt = GetTaskInfo();
- if (fd < 0 || fd >= UFILE_MAX || pt->files[fd] == -1)
- {
- pt->nError = EBADF;
- return -1;
- }
- ifd = pt->files[fd];
- if (nIOCtl & TK_IOCTL_READ_STRING)
- {
- strncpy(ptf->tki.achBuffer, pchBuffer, nSize - 1);
- ptf->tki.achBuffer[nSize - 1] = 0;
- }
- else if (nIOCtl & TK_IOCTL_READ_INT)
- {
- memcpy(ptf->tki.achBuffer, pchBuffer, nSize);
- }
- ptf->iDevice = _files[ifd].tf_dev;
- ptf->tki.nIOCtl = nIOCtl;
- ptf->tki.nSize = nSize;
- iReturn = SendMessage(hwndManager, TKWM_IOCTL, _files[ifd].tf_id, (LPARAM) ptf);
- if (iReturn != -1)
- {
- nSize = ptf->tki.nSize;
- if (nIOCtl & TK_IOCTL_WRITE_STRING)
- {
- strncpy(pchBuffer, ptf->tki.achBuffer, nSize - 1);
- pchBuffer[nSize - 1] = 0;
- }
- else if (nIOCtl & TK_IOCTL_WRITE_INT)
- {
- memcpy(pchBuffer, ptf->tki.achBuffer, nSize);
- }
- }
- return iReturn;
- }
-
- int far _export
- tkern_is_device(int fd,
- char const *pchDevice)
- {
- struct task *pt;
- int ifd;
- int iDevice;
-
- pt = GetTaskInfo();
- if (fd < 0 || fd >= UFILE_MAX || pt->files[fd] == -1)
- {
- pt->nError = EBADF;
- return -1;
- }
- ifd = pt->files[fd];
- strcpy(ptf->achFile, pchDevice);
- iDevice = SendMessage(hwndManager, TKWM_GETDEVNO, 0, (LPARAM) ptf);
- return (_files[ifd].tf_dev == iDevice);
- }
-
- void
- files_init(void)
- {
- memset(_files, 0, sizeof(_files));
- hTFMem = GlobalAlloc(GMEM_FIXED | GMEM_SHARE, sizeof(*ptf));
- ptf = (struct tfunc *) GlobalLock(hTFMem);
-
- }
-
- void
- files_cleanup(void)
- {
- GlobalUnlock(hTFMem);
- GlobalFree(hTFMem);
- }
-
- int far _export
- tkern_valid_file(int fd)
- {
- struct task *pt;
-
- pt = GetTaskInfo();
- return (pt->files[fd] != -1);
- }
-
-