00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
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
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
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
00256
00257
00258 void done_system()
00259 {
00260 }