usbmodeswitch: Updated to v.1.2.6 from shibby's branch.
[tomato.git] / release / src / router / usbmodeswitch / jim / jim-posix.c
blob0cf36049e269f0ca004736708d04cf8976ed42ef
2 /* Jim - POSIX extension
3 * Copyright 2005 Salvatore Sanfilippo <antirez@invece.org>
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * A copy of the license is also included in the source distribution
12 * of Jim, as a TXT file name called LICENSE.
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
21 #include <sys/types.h>
22 #include <sys/time.h>
23 #include <sys/wait.h>
24 #include <unistd.h>
25 #include <string.h>
26 #include <signal.h>
27 #include <errno.h>
29 #include "jim.h"
30 #include "jimautoconf.h"
32 #ifdef HAVE_SYS_SYSINFO_H
33 #include <sys/sysinfo.h>
34 #endif
36 static void Jim_PosixSetError(Jim_Interp *interp)
38 Jim_SetResultString(interp, strerror(errno), -1);
41 #if defined(HAVE_FORK)
42 static int Jim_PosixForkCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
44 pid_t pid;
46 JIM_NOTUSED(argv);
48 if (argc != 1) {
49 Jim_WrongNumArgs(interp, 1, argv, "");
50 return JIM_ERR;
52 if ((pid = fork()) == -1) {
53 Jim_PosixSetError(interp);
54 return JIM_ERR;
56 Jim_SetResultInt(interp, (jim_wide) pid);
57 return JIM_OK;
59 #endif
62 * os.wait ?-nohang? pid
64 * An interface to waitpid(2)
66 * Returns a 3 element list.
68 * If -nohang is specified, and the process is still alive, returns
70 * {0 none 0}
72 * If the process does not exist or has already been waited for, returns:
74 * {-1 error <error-description>}
76 * If the process exited normally, returns:
78 * {<pid> exit <exit-status>}
80 * If the process terminated on a signal, returns:
82 * {<pid> signal <signal-number>}
84 * Otherwise (core dump, stopped, continued, ...), returns:
86 * {<pid> other 0}
88 static int Jim_PosixWaitCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
90 int nohang = 0;
91 long pid;
92 int status;
93 Jim_Obj *listObj;
94 const char *type;
95 int value;
97 if (argc > 1 && Jim_CompareStringImmediate(interp, argv[1], "-nohang")) {
98 nohang = 1;
100 if (argc != nohang + 2) {
101 Jim_WrongNumArgs(interp, 1, argv, "?-nohang? pid");
102 return JIM_ERR;
104 if (Jim_GetLong(interp, argv[nohang + 1], &pid) != JIM_OK) {
105 return JIM_ERR;
108 pid = waitpid(pid, &status, nohang ? WNOHANG : 0);
109 listObj = Jim_NewListObj(interp, NULL, 0);
110 Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, pid));
111 if (pid < 0) {
112 type = "error";
113 value = errno;
115 else if (pid == 0) {
116 type = "none";
117 value = 0;
119 else if (WIFEXITED(status)) {
120 type = "exit";
121 value = WEXITSTATUS(status);
123 else if (WIFSIGNALED(status)) {
124 type = "signal";
125 value = WTERMSIG(status);
127 else {
128 type = "other";
129 value = 0;
132 Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, type, -1));
133 if (pid < 0) {
134 Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, strerror(value), -1));
136 else {
137 Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, value));
139 Jim_SetResult(interp, listObj);
140 return JIM_OK;
143 static int Jim_PosixGetidsCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
145 Jim_Obj *objv[8];
147 if (argc != 1) {
148 Jim_WrongNumArgs(interp, 1, argv, "");
149 return JIM_ERR;
151 objv[0] = Jim_NewStringObj(interp, "uid", -1);
152 objv[1] = Jim_NewIntObj(interp, getuid());
153 objv[2] = Jim_NewStringObj(interp, "euid", -1);
154 objv[3] = Jim_NewIntObj(interp, geteuid());
155 objv[4] = Jim_NewStringObj(interp, "gid", -1);
156 objv[5] = Jim_NewIntObj(interp, getgid());
157 objv[6] = Jim_NewStringObj(interp, "egid", -1);
158 objv[7] = Jim_NewIntObj(interp, getegid());
159 Jim_SetResult(interp, Jim_NewListObj(interp, objv, 8));
160 return JIM_OK;
163 #define JIM_HOST_NAME_MAX 1024
164 static int Jim_PosixGethostnameCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
166 char *buf;
167 int rc = JIM_OK;
169 if (argc != 1) {
170 Jim_WrongNumArgs(interp, 1, argv, "");
171 return JIM_ERR;
173 buf = Jim_Alloc(JIM_HOST_NAME_MAX);
174 if (gethostname(buf, JIM_HOST_NAME_MAX) == -1) {
175 Jim_PosixSetError(interp);
176 rc = JIM_ERR;
178 else {
179 Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, buf, -1));
181 return rc;
184 static int Jim_PosixUptimeCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
186 #ifdef HAVE_STRUCT_SYSINFO_UPTIME
187 struct sysinfo info;
189 if (argc != 1) {
190 Jim_WrongNumArgs(interp, 1, argv, "");
191 return JIM_ERR;
194 if (sysinfo(&info) == -1) {
195 Jim_PosixSetError(interp);
196 return JIM_ERR;
199 Jim_SetResultInt(interp, info.uptime);
200 #else
201 Jim_SetResultInt(interp, (long)time(NULL));
202 #endif
203 return JIM_OK;
206 static int Jim_PosixPidCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
208 if (argc != 1) {
209 Jim_WrongNumArgs(interp, 1, argv, "");
210 return JIM_ERR;
213 Jim_SetResultInt(interp, getpid());
214 return JIM_OK;
217 int Jim_posixInit(Jim_Interp *interp)
219 if (Jim_PackageProvide(interp, "posix", "1.0", JIM_ERRMSG))
220 return JIM_ERR;
222 #ifdef HAVE_FORK
223 Jim_CreateCommand(interp, "os.fork", Jim_PosixForkCommand, NULL, NULL);
224 #endif
225 Jim_CreateCommand(interp, "os.wait", Jim_PosixWaitCommand, NULL, NULL);
226 Jim_CreateCommand(interp, "os.getids", Jim_PosixGetidsCommand, NULL, NULL);
227 Jim_CreateCommand(interp, "os.gethostname", Jim_PosixGethostnameCommand, NULL, NULL);
228 Jim_CreateCommand(interp, "os.uptime", Jim_PosixUptimeCommand, NULL, NULL);
229 Jim_CreateCommand(interp, "pid", Jim_PosixPidCommand, NULL, NULL);
230 return JIM_OK;