c — PHP exec не запускает мой скрипт как задумано

Привет товарищи программисты,

Я работаю над проектом моего бакалавра и попал в небольшую проблему.

Цель состоит в том, чтобы создать веб-приложение, которое может управлять и модифицировать ввод / вывод WAGO PLC 750-8202 (вы можете представить это как некий промышленный Raspberry PI), на котором работает встроенный linux с веб-сервером lighttpd. Я сделал несколько C-скриптов, которые используют функции DAL (HAL), которые обеспечивает ПЛК.

Теперь я хочу связать его с моим веб-приложением / сайтом. У меня есть простая страница PHP (игнорируйте кнопку, она ничего не делает):

<html>
<head>
<title>PHP Test</title>
</head>
<body>
<button value="CLICK ME">CLICK ME</button>
<?php
echo system("kbusdemo1");
?>
</body>
</html>

Как видите, я вызываю скрипт kbusdemo1. Предполагается распечатать значения цифровых входов. Если я вызываю его с терминала SSH, подключенного к моему ПЛК от имени пользователя root, он работает просто отлично. Однако, если я вызываю его с сайта PHP (как показано выше), он выполняет НО, но не показывает значения цифрового ввода, а вместо этого выдает ошибку «Нет устройства на KBUS». Вы можете увидеть точную строку в коде ниже.

KBUS — это шина, к которой подключены все модули ввода / вывода ПЛК. По сути, похоже, что он не выполняет правильно функции, предоставляемые разработчиком ПЛК.

Вот код, написанный на C (kbusdemo1.c)

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>
#include <sched.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>

#include <dal/adi_application_interface.h>

#define KBUS_MAINPRIO 40

int
main(void)
{
// vars for ADI-interface
tDeviceInfo deviceList[10];          // the list of devices given by the ADI
size_t nrDevicesFound;               // number of devices found
size_t nrKbusFound;                  // position of the kbus in the list
tDeviceId kbusDeviceId;              // device ID from the ADI
tApplicationDeviceInterface * adi;   // pointer to the application interface
uint32_t taskId = 0;                 // task Id
tApplicationStateChangedEvent event; // var for the event interface of the ADI
int AnWriteSelect, AnReadSelect, i, j, k, DigWriteOffset = 32, DigReadOffset = 32, vyber;
int DigWrite[8] = {0}, DigRead[8] = {0};
char DigWriteBuff[8];
int16_t AnRead, AnWrite;
bool loop = false;

struct sched_param s_param;

// program start
//printf("**************************************************\n");
//printf("***             KBUS test app                  ***\n");
//printf("**************************************************\n");

// clear process memory
memset(DigWrite, 0, sizeof(DigWrite));
memset(DigWriteBuff, 0, sizeof(DigWriteBuff));
memset(DigRead, 0, sizeof(DigRead));

// connect to ADI-interface
adi = adi_GetApplicationInterface();

// init interface
adi->Init();

// scan devices
adi->ScanDevices();
adi->GetDeviceList(sizeof(deviceList), deviceList, &nrDevicesFound);

// find kbus device
nrKbusFound = -1;
for (i = 0; i < nrDevicesFound; ++i)
{
if (strcmp(deviceList[i].DeviceName, "libpackbus") == 0)
{
nrKbusFound = i;
printf("KBUS device found as %i\n", i);
}
}

// kbus not found > exit
if (nrKbusFound == -1)
{
printf("No device found on KBUS\n");
adi->Exit(); // disconnect ADI-Interface
return -1; // exit program
}

// switch to RT Priority
s_param.sched_priority = KBUS_MAINPRIO;
sched_setscheduler(0, SCHED_FIFO, &s_param);
printf("Switch to RT priority 'KBUS_MAINPRIO'\n");

// open kbus device
kbusDeviceId = deviceList[nrKbusFound].DeviceId;
if (adi->OpenDevice(kbusDeviceId) != DAL_SUCCESS)
{
printf("Opening KBUS device failed\n");
adi->Exit(); // disconnect ADI-Interface
return -2; // exit program
}
//printf("Otevření KBUS zařízení OK\n");// set application state to "Unconfigured" to let library drive kbus by them selve.
// In this mode library set up a thread who drive the kbus cyclic.
event.State = ApplicationState_Unconfigured;
if (adi->ApplicationStateChanged(event) != DAL_SUCCESS)
{
// Set application state to "Unconfigured" failed
printf("Setting Unconfigured application state failed\n");
adi->CloseDevice(kbusDeviceId); // close kbus device
adi->Exit(); // disconnect ADI-Interface
return -3; // exit programm
}
printf("Unconfigured application state OK\n");

adi->WatchdogTrigger();
adi->ReadStart(kbusDeviceId, taskId);
for (k = 0; k < 8; k++)
{
adi->ReadBool(kbusDeviceId,taskId,DigReadOffset,(int*) &DigRead[k]);
DigReadOffset++;
}
adi->ReadEnd(kbusDeviceId, taskId);
for(k = 0; k < 8; k++)
printf("%d ",DigRead[k]);
printf("\n \n");
DigReadOffset = 32;adi->CloseDevice(kbusDeviceId);
adi->Exit();
return 0;
}

Итак, вопрос в том, использую ли я правильный метод? Подходит ли PHP exec для такого рода приложений? Если так, есть идеи, где я делаю что-то не так?

Я понимаю, что это проблема конкретного устройства. В настоящее время у меня нет идей, и любой намек, который может указать мне правильное направление, бесценен.

Спасибо за ваше время.


РЕДАКТИРОВАТЬ

Хорошо, я попытался редактировать sudoers с

sudo nano /etc/sudoers

Visudo не реализован в системе ПЛК Linux. Я изменил его на код, размещенный ниже, но если я попытаюсь запустить его, как вы предложили (с su www), он все равно не будет работать. Что я делаю неправильно?

Спасибо за ваши предложения.

# sudoers file.
#
# This file MUST be edited with the 'visudo' command as root.
#
# See the sudoers man page for the details on how to write a sudoers file.
#

# Host alias specification

# User alias specification

# Cmnd alias specification

# Defaults specification

# Runas alias specification

# User privilege specification
root  ALL=(ALL) SETENV: ALL
admin ALL=NOPASSWD: /etc/config-tools/get_user_info
user ALL=NOPASSWD: /etc/config-tools/get_user_info
www ALL=(ALL) NOPASSWD:ALL

# Uncomment to allow people in group wheel to run all commands
# and set environment variables.
# %wheel  ALL=(ALL) SETENV: ALL

# Same thing without a password
# %wheel  ALL=(ALL) NOPASSWD: SETENV: ALL

# Samples
# %users  ALL=/sbin/mount /cdrom,/sbin/umount /cdrom
# %users  localhost=/sbin/shutdown -h now

0

Решение

если вы запускаете скрипт от имени пользователя root, у него есть другие права, чем у пользователя, под которым работает lighthttpd.

  • установить соответствующие права для пользователя или группы (www или www-data, см. lighthttpd config)
  • проверьте запуск под этим пользователем, в консоли для переключения от использования root

    # su — www

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]