2 * Jim - POSIX extension
4 * Copyright 2005 Salvatore Sanfilippo <antirez@invece.org>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials
15 * provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 * The views and conclusions contained in the software and documentation
31 * are those of the authors and should not be interpreted as representing
32 * official policies, either expressed or implied, of the Jim Tcl Project.
35 #include <sys/types.h>
43 #include "jimautoconf.h"
46 #ifdef HAVE_SYS_SYSINFO_H
47 #include <sys/sysinfo.h>
50 static void Jim_PosixSetError(Jim_Interp
*interp
)
52 Jim_SetResultString(interp
, strerror(errno
), -1);
55 #if defined(HAVE_FORK)
56 static int Jim_PosixForkCommand(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
63 Jim_WrongNumArgs(interp
, 1, argv
, "");
66 if ((pid
= fork()) == -1) {
67 Jim_PosixSetError(interp
);
70 Jim_SetResultInt(interp
, (jim_wide
) pid
);
76 * os.wait ?-nohang? pid
78 * An interface to waitpid(2)
80 * Returns a 3 element list.
82 * If -nohang is specified, and the process is still alive, returns
86 * If the process does not exist or has already been waited for, returns:
88 * {-1 error <error-description>}
90 * If the process exited normally, returns:
92 * {<pid> exit <exit-status>}
94 * If the process terminated on a signal, returns:
96 * {<pid> signal <signal-number>}
98 * Otherwise (core dump, stopped, continued, ...), returns:
102 static int Jim_PosixWaitCommand(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
111 if (argc
> 1 && Jim_CompareStringImmediate(interp
, argv
[1], "-nohang")) {
114 if (argc
!= nohang
+ 2) {
115 Jim_WrongNumArgs(interp
, 1, argv
, "?-nohang? pid");
118 if (Jim_GetLong(interp
, argv
[nohang
+ 1], &pid
) != JIM_OK
) {
122 pid
= waitpid(pid
, &status
, nohang
? WNOHANG
: 0);
123 listObj
= Jim_NewListObj(interp
, NULL
, 0);
124 Jim_ListAppendElement(interp
, listObj
, Jim_NewIntObj(interp
, pid
));
133 else if (WIFEXITED(status
)) {
135 value
= WEXITSTATUS(status
);
137 else if (WIFSIGNALED(status
)) {
139 value
= WTERMSIG(status
);
146 Jim_ListAppendElement(interp
, listObj
, Jim_NewStringObj(interp
, type
, -1));
148 Jim_ListAppendElement(interp
, listObj
, Jim_NewStringObj(interp
, strerror(value
), -1));
151 Jim_ListAppendElement(interp
, listObj
, Jim_NewIntObj(interp
, value
));
153 Jim_SetResult(interp
, listObj
);
157 static int Jim_PosixGetidsCommand(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
162 Jim_WrongNumArgs(interp
, 1, argv
, "");
165 objv
[0] = Jim_NewStringObj(interp
, "uid", -1);
166 objv
[1] = Jim_NewIntObj(interp
, getuid());
167 objv
[2] = Jim_NewStringObj(interp
, "euid", -1);
168 objv
[3] = Jim_NewIntObj(interp
, geteuid());
169 objv
[4] = Jim_NewStringObj(interp
, "gid", -1);
170 objv
[5] = Jim_NewIntObj(interp
, getgid());
171 objv
[6] = Jim_NewStringObj(interp
, "egid", -1);
172 objv
[7] = Jim_NewIntObj(interp
, getegid());
173 Jim_SetResult(interp
, Jim_NewListObj(interp
, objv
, 8));
177 #define JIM_HOST_NAME_MAX 1024
178 static int Jim_PosixGethostnameCommand(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
184 Jim_WrongNumArgs(interp
, 1, argv
, "");
187 buf
= Jim_Alloc(JIM_HOST_NAME_MAX
);
188 if (gethostname(buf
, JIM_HOST_NAME_MAX
) == -1) {
189 Jim_PosixSetError(interp
);
194 Jim_SetResult(interp
, Jim_NewStringObjNoAlloc(interp
, buf
, -1));
199 static int Jim_PosixUptimeCommand(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
201 #ifdef HAVE_STRUCT_SYSINFO_UPTIME
205 Jim_WrongNumArgs(interp
, 1, argv
, "");
209 if (sysinfo(&info
) == -1) {
210 Jim_PosixSetError(interp
);
214 Jim_SetResultInt(interp
, info
.uptime
);
216 Jim_SetResultInt(interp
, (long)time(NULL
));
221 static int Jim_PosixPidCommand(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
224 Jim_WrongNumArgs(interp
, 1, argv
, "");
228 Jim_SetResultInt(interp
, getpid());
232 int Jim_posixInit(Jim_Interp
*interp
)
234 if (Jim_PackageProvide(interp
, "posix", "1.0", JIM_ERRMSG
))
238 Jim_CreateCommand(interp
, "os.fork", Jim_PosixForkCommand
, NULL
, NULL
);
240 Jim_CreateCommand(interp
, "os.wait", Jim_PosixWaitCommand
, NULL
, NULL
);
241 Jim_CreateCommand(interp
, "os.getids", Jim_PosixGetidsCommand
, NULL
, NULL
);
242 Jim_CreateCommand(interp
, "os.gethostname", Jim_PosixGethostnameCommand
, NULL
, NULL
);
243 Jim_CreateCommand(interp
, "os.uptime", Jim_PosixUptimeCommand
, NULL
, NULL
);
244 Jim_CreateCommand(interp
, "pid", Jim_PosixPidCommand
, NULL
, NULL
);