Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

htsys.cc

Go to the documentation of this file.
00001 /*
00002  *      HT Editor
00003  *      htsys.cc (POSIX implementation)
00004  *
00005  *      Copyright (C) 1999-2002 Stefan Weyergraf (stefan@weyergraf.de)
00006  *
00007  *      This program is free software; you can redistribute it and/or modify
00008  *      it under the terms of the GNU General Public License version 2 as
00009  *      published by the Free Software Foundation.
00010  *
00011  *      This program is distributed in the hope that it will be useful,
00012  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *      GNU General Public License for more details.
00015  *
00016  *      You should have received a copy of the GNU General Public License
00017  *      along with this program; if not, write to the Free Software
00018  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  */
00020 
00021 #include "htsys.h"
00022 
00023 #include <dirent.h>
00024 #include <errno.h>
00025 #include <fcntl.h>
00026 #include <limits.h>
00027 #include <signal.h>
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include <string.h>
00031 #include <sys/stat.h>
00032 #include <sys/types.h>
00033 #include <sys/time.h>
00034 #include <sys/wait.h>
00035 #include <unistd.h>
00036                  
00037 int sys_canonicalize(char *result, const char *filename)
00038 {
00039         return (realpath(filename, result)==result) ? 0 : ENOENT;
00040 }
00041 
00042 struct posixfindstate {
00043         DIR *fhandle;
00044 };
00045 
00046 char sys_find_dirname[HT_NAME_MAX];
00047 
00048 int sys_findclose(pfind_t *pfind)
00049 {
00050         int r = closedir(((posixfindstate*)pfind->findstate)->fhandle);
00051         free(pfind->findstate);
00052         return r;
00053 }
00054 
00055 int sys_findfirst(const char *dirname, pfind_t *pfind)
00056 {
00057         int r;
00058         pfind->findstate = malloc(sizeof (posixfindstate));
00059         posixfindstate *pfs = (posixfindstate*)pfind->findstate;
00060         if ((pfs->fhandle = opendir(dirname))) {
00061                 strcpy(sys_find_dirname, dirname);
00062                 char *s = sys_find_dirname+strlen(sys_find_dirname);
00063                 if ((s > sys_find_dirname) && (*(s-1) != '/')) {
00064                     *(s++) = '/';
00065                     *s = 0;
00066                 }
00067                 r = sys_findnext(pfind);
00068         } else r = errno ? errno : ENOENT;
00069         if (r) free(pfind->findstate);
00070         return r;
00071 }
00072 
00073 int sys_findnext(pfind_t *pfind)
00074 {
00075         posixfindstate *pfs = (posixfindstate*)pfind->findstate;
00076         struct dirent *d;
00077         if ((d = readdir(pfs->fhandle))) {
00078                 pfind->name = d->d_name;
00079                 char *s = sys_find_dirname+strlen(sys_find_dirname);
00080                 strcpy(s, d->d_name);
00081                 sys_pstat(&pfind->stat, sys_find_dirname);
00082                 *s = 0;
00083                 return 0;
00084         }
00085         return ENOENT;
00086 }
00087 
00088 int sys_pstat(pstat_t *s, const char *filename)
00089 {
00090         struct stat st;
00091         errno = 0;
00092         int e = stat(filename, &st);
00093         if (e) return errno ? errno : ENOENT;
00094         s->caps = pstat_ctime|pstat_mtime|pstat_atime|pstat_uid|pstat_gid|pstat_mode_all|pstat_size|pstat_inode;
00095         s->ctime = st.st_ctime;
00096         s->mtime = st.st_mtime;
00097         s->atime = st.st_atime;
00098         s->gid = st.st_uid;
00099         s->uid = st.st_gid;
00100         s->mode = sys_ht_mode(st.st_mode);
00101         s->size = st.st_size;
00102         s->size_high = 0;
00103         s->fsid = st.st_ino;
00104         return 0;
00105 }
00106 
00107 void sys_suspend()
00108 {
00109         timeval tm;
00110         fd_set zerofds;
00111         FD_ZERO(&zerofds);
00112         
00113         tm.tv_sec = 0;
00114         tm.tv_usec = 100;
00115         select(0, &zerofds, &zerofds, &zerofds, &tm);
00116 }
00117 
00118 int sys_get_free_mem()
00119 {
00120         return 0;
00121 }
00122 
00123 int sys_truncate(const char *filename, FILEOFS ofs)
00124 {
00125         int fd = open(filename, O_RDWR, 0);
00126         if (fd < 0) return errno;
00127         if (ftruncate(fd, ofs) != 0) return errno;
00128         return close(fd);
00129 }
00130 
00131 int sys_deletefile(const char *filename)
00132 {
00133         return remove(filename);
00134 }
00135 
00136 bool sys_is_path_delim(char c)
00137 {
00138         return c == '/';
00139 }
00140 
00141 int sys_filename_cmp(const char *a, const char *b)
00142 {
00143         while (*a && *b) {
00144                 if (sys_is_path_delim(*a) && sys_is_path_delim(*b)) {
00145                 } else if (*a != *b) {
00146                         break;
00147                 }
00148                 a++;
00149                 b++;
00150         }
00151         return *a - *b;
00152 }
00153 
00154 /*
00155  *      POSIX IPC
00156  */
00157  
00158 static int child_pid = -1;
00159 
00160 void SIGCHLD_sigaction(int i, siginfo_t *info, void *v)
00161 {
00162         int j;
00163         waitpid(child_pid, &j, WNOHANG);
00164         child_pid = -1;
00165 }
00166 
00167 int sys_ipc_exec(ht_streamfile **in, ht_streamfile **out, ht_streamfile **err, int *handle, const char *cmd, int options)
00168 {
00169         if (child_pid != -1) return EBUSY;
00170         int in_fds[2];
00171         int out_fds[2];
00172         int err_fds[2];
00173         int pid;
00174         if (pipe(in_fds)) return errno;
00175         if (pipe(out_fds)) return errno;
00176         if (pipe(err_fds)) return errno;
00177         pid = fork();
00178         if (pid > 0) {
00179                 /* parent process */
00180                 close(in_fds[0]);
00181                 close(out_fds[1]);
00182                 close(err_fds[1]);
00183                 int in_fd = in_fds[1];
00184                 int out_fd = out_fds[0];
00185                 int err_fd = err_fds[0];
00186                 ht_sys_file *f;
00187                 f = new ht_sys_file();
00188                 f->init(in_fd, true, FAM_WRITE);
00189                 *in = f;
00190                 f = new ht_sys_file();
00191                 f->init(out_fd, true, FAM_READ);
00192                 *out = f;
00193                 f = new ht_sys_file();
00194                 f->init(err_fd, true, FAM_READ);
00195                 *err = f;
00196                 *handle = pid;
00197                 if (fcntl(out_fd, F_SETFL, O_NONBLOCK) ||
00198                 fcntl(err_fd, F_SETFL, O_NONBLOCK)) return errno;
00199                 child_pid = pid;
00200                 return 0;
00201         } else if (pid == 0) {
00202                 /* child process */
00203                 close(in_fds[1]);
00204                 close(out_fds[0]);
00205                 close(err_fds[0]);
00206                 dup2(in_fds[0], STDIN_FILENO);
00207                 dup2(out_fds[1], STDOUT_FILENO);
00208                 dup2(err_fds[1], STDERR_FILENO);
00209                 close(in_fds[0]);
00210                 close(out_fds[1]);
00211                 close(err_fds[1]);
00212                 execl(cmd, cmd, NULL);
00213                 exit(1);
00214         } else return errno;
00215 }
00216 
00217 bool sys_ipc_is_valid(int handle)
00218 {
00219         return child_pid == handle;
00220 }
00221 
00222 int sys_ipc_terminate(int handle)
00223 {
00224         if (child_pid == handle) {
00225                 kill(handle, SIGTERM);
00226                 child_pid = -1;
00227                 return 0;
00228         }               
00229         return EINVAL;
00230 }
00231 
00232 int sys_get_caps()
00233 {
00234         return SYSCAP_NONBLOCKING_IPC;
00235 }
00236 
00237 /*
00238  *      INIT
00239  */
00240  
00241 bool init_system()
00242 {
00243         setuid( getuid() );
00244         struct sigaction sa;
00245         
00246         sa.sa_sigaction = SIGCHLD_sigaction;
00247         sigemptyset(&sa.sa_mask);
00248         sa.sa_flags = SA_SIGINFO;
00249         
00250         sigaction(SIGCHLD, &sa, NULL);
00251         return true;
00252 }
00253 
00254 /*
00255  *      DONE
00256  */
00257 
00258 void done_system()
00259 {
00260 }

Generated on Fri May 7 21:15:37 2004 by doxygen 1.3.5