xref: /qemu/os-posix.c (revision 59a5264b994343f01d19faf95c0e5df70346ded8)
186b645e7SJes Sorensen /*
286b645e7SJes Sorensen  * os-posix.c
386b645e7SJes Sorensen  *
486b645e7SJes Sorensen  * Copyright (c) 2003-2008 Fabrice Bellard
586b645e7SJes Sorensen  * Copyright (c) 2010 Red Hat, Inc.
686b645e7SJes Sorensen  *
786b645e7SJes Sorensen  * Permission is hereby granted, free of charge, to any person obtaining a copy
886b645e7SJes Sorensen  * of this software and associated documentation files (the "Software"), to deal
986b645e7SJes Sorensen  * in the Software without restriction, including without limitation the rights
1086b645e7SJes Sorensen  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1186b645e7SJes Sorensen  * copies of the Software, and to permit persons to whom the Software is
1286b645e7SJes Sorensen  * furnished to do so, subject to the following conditions:
1386b645e7SJes Sorensen  *
1486b645e7SJes Sorensen  * The above copyright notice and this permission notice shall be included in
1586b645e7SJes Sorensen  * all copies or substantial portions of the Software.
1686b645e7SJes Sorensen  *
1786b645e7SJes Sorensen  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1886b645e7SJes Sorensen  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1986b645e7SJes Sorensen  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
2086b645e7SJes Sorensen  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2186b645e7SJes Sorensen  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2286b645e7SJes Sorensen  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2386b645e7SJes Sorensen  * THE SOFTWARE.
2486b645e7SJes Sorensen  */
2586b645e7SJes Sorensen 
2686b645e7SJes Sorensen #include <unistd.h>
2786b645e7SJes Sorensen #include <fcntl.h>
2886b645e7SJes Sorensen #include <signal.h>
298d963e6aSJes Sorensen #include <sys/types.h>
308d963e6aSJes Sorensen #include <sys/wait.h>
316170540bSJes Sorensen #include <libgen.h>
3286b645e7SJes Sorensen 
3386b645e7SJes Sorensen /* Needed early for CONFIG_BSD etc. */
3486b645e7SJes Sorensen #include "config-host.h"
3586b645e7SJes Sorensen #include "sysemu.h"
36*59a5264bSJes Sorensen #include "net/slirp.h"
37*59a5264bSJes Sorensen #include "qemu-options.h"
3886b645e7SJes Sorensen 
39fe98ac14SJes Sorensen void os_setup_early_signal_handling(void)
4086b645e7SJes Sorensen {
4186b645e7SJes Sorensen     struct sigaction act;
4286b645e7SJes Sorensen     sigfillset(&act.sa_mask);
4386b645e7SJes Sorensen     act.sa_flags = 0;
4486b645e7SJes Sorensen     act.sa_handler = SIG_IGN;
4586b645e7SJes Sorensen     sigaction(SIGPIPE, &act, NULL);
4686b645e7SJes Sorensen }
478d963e6aSJes Sorensen 
488d963e6aSJes Sorensen static void termsig_handler(int signal)
498d963e6aSJes Sorensen {
508d963e6aSJes Sorensen     qemu_system_shutdown_request();
518d963e6aSJes Sorensen }
528d963e6aSJes Sorensen 
538d963e6aSJes Sorensen static void sigchld_handler(int signal)
548d963e6aSJes Sorensen {
558d963e6aSJes Sorensen     waitpid(-1, NULL, WNOHANG);
568d963e6aSJes Sorensen }
578d963e6aSJes Sorensen 
588d963e6aSJes Sorensen void os_setup_signal_handling(void)
598d963e6aSJes Sorensen {
608d963e6aSJes Sorensen     struct sigaction act;
618d963e6aSJes Sorensen 
628d963e6aSJes Sorensen     memset(&act, 0, sizeof(act));
638d963e6aSJes Sorensen     act.sa_handler = termsig_handler;
648d963e6aSJes Sorensen     sigaction(SIGINT,  &act, NULL);
658d963e6aSJes Sorensen     sigaction(SIGHUP,  &act, NULL);
668d963e6aSJes Sorensen     sigaction(SIGTERM, &act, NULL);
678d963e6aSJes Sorensen 
688d963e6aSJes Sorensen     act.sa_handler = sigchld_handler;
698d963e6aSJes Sorensen     act.sa_flags = SA_NOCLDSTOP;
708d963e6aSJes Sorensen     sigaction(SIGCHLD, &act, NULL);
718d963e6aSJes Sorensen }
726170540bSJes Sorensen 
736170540bSJes Sorensen /* Find a likely location for support files using the location of the binary.
746170540bSJes Sorensen    For installed binaries this will be "$bindir/../share/qemu".  When
756170540bSJes Sorensen    running from the build tree this will be "$bindir/../pc-bios".  */
766170540bSJes Sorensen #define SHARE_SUFFIX "/share/qemu"
776170540bSJes Sorensen #define BUILD_SUFFIX "/pc-bios"
786170540bSJes Sorensen char *os_find_datadir(const char *argv0)
796170540bSJes Sorensen {
806170540bSJes Sorensen     char *dir;
816170540bSJes Sorensen     char *p = NULL;
826170540bSJes Sorensen     char *res;
836170540bSJes Sorensen     char buf[PATH_MAX];
846170540bSJes Sorensen     size_t max_len;
856170540bSJes Sorensen 
866170540bSJes Sorensen #if defined(__linux__)
876170540bSJes Sorensen     {
886170540bSJes Sorensen         int len;
896170540bSJes Sorensen         len = readlink("/proc/self/exe", buf, sizeof(buf) - 1);
906170540bSJes Sorensen         if (len > 0) {
916170540bSJes Sorensen             buf[len] = 0;
926170540bSJes Sorensen             p = buf;
936170540bSJes Sorensen         }
946170540bSJes Sorensen     }
956170540bSJes Sorensen #elif defined(__FreeBSD__)
966170540bSJes Sorensen     {
976170540bSJes Sorensen         static int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
986170540bSJes Sorensen         size_t len = sizeof(buf) - 1;
996170540bSJes Sorensen 
1006170540bSJes Sorensen         *buf = '\0';
1016170540bSJes Sorensen         if (!sysctl(mib, sizeof(mib)/sizeof(*mib), buf, &len, NULL, 0) &&
1026170540bSJes Sorensen             *buf) {
1036170540bSJes Sorensen             buf[sizeof(buf) - 1] = '\0';
1046170540bSJes Sorensen             p = buf;
1056170540bSJes Sorensen         }
1066170540bSJes Sorensen     }
1076170540bSJes Sorensen #endif
1086170540bSJes Sorensen     /* If we don't have any way of figuring out the actual executable
1096170540bSJes Sorensen        location then try argv[0].  */
1106170540bSJes Sorensen     if (!p) {
1116170540bSJes Sorensen         p = realpath(argv0, buf);
1126170540bSJes Sorensen         if (!p) {
1136170540bSJes Sorensen             return NULL;
1146170540bSJes Sorensen         }
1156170540bSJes Sorensen     }
1166170540bSJes Sorensen     dir = dirname(p);
1176170540bSJes Sorensen     dir = dirname(dir);
1186170540bSJes Sorensen 
1196170540bSJes Sorensen     max_len = strlen(dir) +
1206170540bSJes Sorensen         MAX(strlen(SHARE_SUFFIX), strlen(BUILD_SUFFIX)) + 1;
1216170540bSJes Sorensen     res = qemu_mallocz(max_len);
1226170540bSJes Sorensen     snprintf(res, max_len, "%s%s", dir, SHARE_SUFFIX);
1236170540bSJes Sorensen     if (access(res, R_OK)) {
1246170540bSJes Sorensen         snprintf(res, max_len, "%s%s", dir, BUILD_SUFFIX);
1256170540bSJes Sorensen         if (access(res, R_OK)) {
1266170540bSJes Sorensen             qemu_free(res);
1276170540bSJes Sorensen             res = NULL;
1286170540bSJes Sorensen         }
1296170540bSJes Sorensen     }
1306170540bSJes Sorensen 
1316170540bSJes Sorensen     return res;
1326170540bSJes Sorensen }
1336170540bSJes Sorensen #undef SHARE_SUFFIX
1346170540bSJes Sorensen #undef BUILD_SUFFIX
135*59a5264bSJes Sorensen 
136*59a5264bSJes Sorensen /*
137*59a5264bSJes Sorensen  * Parse OS specific command line options.
138*59a5264bSJes Sorensen  * return 0 if option handled, -1 otherwise
139*59a5264bSJes Sorensen  */
140*59a5264bSJes Sorensen void os_parse_cmd_args(int index, const char *optarg)
141*59a5264bSJes Sorensen {
142*59a5264bSJes Sorensen     switch (index) {
143*59a5264bSJes Sorensen #ifdef CONFIG_SLIRP
144*59a5264bSJes Sorensen     case QEMU_OPTION_smb:
145*59a5264bSJes Sorensen         if (net_slirp_smb(optarg) < 0)
146*59a5264bSJes Sorensen             exit(1);
147*59a5264bSJes Sorensen         break;
148*59a5264bSJes Sorensen #endif
149*59a5264bSJes Sorensen     }
150*59a5264bSJes Sorensen     return;
151*59a5264bSJes Sorensen }
152