aio recvfrom was not null terminating the result
[jimtcl.git] / jim-posix.c
blob61f5af80c949302dabf4cd9600f22b598058732f
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"
31 #ifdef HAVE_SYSINFO
32 #include <sys/sysinfo.h>
33 #endif
35 static void Jim_PosixSetError(Jim_Interp *interp)
37 Jim_SetResultString(interp, strerror(errno), -1);
40 #ifdef HAVE_FORK
41 static int Jim_PosixForkCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
43 pid_t pid;
45 JIM_NOTUSED(argv);
47 if (argc != 1) {
48 Jim_WrongNumArgs(interp, 1, argv, "");
49 return JIM_ERR;
51 if ((pid = fork()) == -1) {
52 Jim_PosixSetError(interp);
53 return JIM_ERR;
55 Jim_SetResultInt(interp, (jim_wide) pid);
56 return JIM_OK;
58 #endif
61 * os.wait ?-nohang? pid
63 * An interface to waitpid(2)
65 * Returns a 3 element list.
67 * If -nohang is specified, and the process is still alive, returns
69 * {0 none 0}
71 * If the process does not exist or has already been waited for, returns:
73 * {-1 error <error-description>}
75 * If the process exited normally, returns:
77 * {<pid> exit <exit-status>}
79 * If the process terminated on a signal, returns:
81 * {<pid> signal <signal-number>}
83 * Otherwise (core dump, stopped, continued, ...), returns:
85 * {<pid> other 0}
87 static int Jim_PosixWaitCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
89 int nohang = 0;
90 long pid;
91 int status;
92 Jim_Obj *listObj;
93 const char *type;
94 int value;
96 if (argc > 1 && Jim_CompareStringImmediate(interp, argv[1], "-nohang")) {
97 nohang = 1;
99 if (argc != nohang + 2) {
100 Jim_WrongNumArgs(interp, 1, argv, "?-nohang? pid");
101 return JIM_ERR;
103 if (Jim_GetLong(interp, argv[nohang + 1], &pid) != JIM_OK) {
104 return JIM_ERR;
107 pid = waitpid(pid, &status, nohang ? WNOHANG : 0);
108 listObj = Jim_NewListObj(interp, NULL, 0);
109 Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, pid));
110 if (pid < 0) {
111 type = "error";
112 value = errno;
114 else if (pid == 0) {
115 type = "none";
116 value = 0;
118 else if (WIFEXITED(status)) {
119 type = "exit";
120 value = WEXITSTATUS(status);
122 else if (WIFSIGNALED(status)) {
123 type = "signal";
124 value = WTERMSIG(status);
126 else {
127 type = "other";
128 value = 0;
131 Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, type, -1));
132 if (pid < 0) {
133 Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, strerror(value), -1));
135 else {
136 Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, value));
138 Jim_SetResult(interp, listObj);
139 return JIM_OK;
142 static int Jim_PosixGetidsCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
144 Jim_Obj *objv[8];
146 if (argc != 1) {
147 Jim_WrongNumArgs(interp, 1, argv, "");
148 return JIM_ERR;
150 objv[0] = Jim_NewStringObj(interp, "uid", -1);
151 objv[1] = Jim_NewIntObj(interp, getuid());
152 objv[2] = Jim_NewStringObj(interp, "euid", -1);
153 objv[3] = Jim_NewIntObj(interp, geteuid());
154 objv[4] = Jim_NewStringObj(interp, "gid", -1);
155 objv[5] = Jim_NewIntObj(interp, getgid());
156 objv[6] = Jim_NewStringObj(interp, "egid", -1);
157 objv[7] = Jim_NewIntObj(interp, getegid());
158 Jim_SetResult(interp, Jim_NewListObj(interp, objv, 8));
159 return JIM_OK;
162 #define JIM_HOST_NAME_MAX 1024
163 static int Jim_PosixGethostnameCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
165 char buf[JIM_HOST_NAME_MAX];
167 if (argc != 1) {
168 Jim_WrongNumArgs(interp, 1, argv, "");
169 return JIM_ERR;
171 if (gethostname(buf, JIM_HOST_NAME_MAX) == -1) {
172 Jim_PosixSetError(interp);
173 return JIM_ERR;
175 Jim_SetResultString(interp, buf, -1);
176 return JIM_OK;
179 static int Jim_PosixUptimeCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
181 #ifdef HAVE_SYSINFO
182 struct sysinfo info;
184 if (argc != 1) {
185 Jim_WrongNumArgs(interp, 1, argv, "");
186 return JIM_ERR;
189 if (sysinfo(&info) == -1) {
190 Jim_PosixSetError(interp);
191 return JIM_ERR;
194 Jim_SetResultInt(interp, info.uptime);
195 #else
196 Jim_SetResultInt(interp, (long)time(NULL));
197 #endif
198 return JIM_OK;
201 static int Jim_PosixPidCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
203 if (argc != 1) {
204 Jim_WrongNumArgs(interp, 1, argv, "");
205 return JIM_ERR;
208 Jim_SetResultInt(interp, getpid());
209 return JIM_OK;
212 int Jim_posixInit(Jim_Interp *interp)
214 #ifdef HAVE_FORK
215 Jim_CreateCommand(interp, "os.fork", Jim_PosixForkCommand, NULL, NULL);
216 #endif
217 Jim_CreateCommand(interp, "os.wait", Jim_PosixWaitCommand, NULL, NULL);
218 Jim_CreateCommand(interp, "os.getids", Jim_PosixGetidsCommand, NULL, NULL);
219 Jim_CreateCommand(interp, "os.gethostname", Jim_PosixGethostnameCommand, NULL, NULL);
220 Jim_CreateCommand(interp, "os.uptime", Jim_PosixUptimeCommand, NULL, NULL);
221 Jim_CreateCommand(interp, "pid", Jim_PosixPidCommand, NULL, NULL);
222 return JIM_OK;